when().thenAnswer() not firing in blocTest

huangapple go评论66阅读模式
英文:

when().thenAnswer() not firing in blocTest

问题

在测试中,似乎when().thenAnswer()这些行不起作用,而且测试出现了错误。这可能是因为模拟对象未按预期工作,导致了测试失败。你可以尝试以下几种方法来解决这个问题:

  1. 确保MockFlutterSecureStorage被正确设置为模拟对象。检查您的@GenerateNiceMocks注解是否包含正确的类。

  2. 确保导入了正确版本的mockito库。有时版本问题可能会导致模拟不起作用。

  3. 检查loadStoredCredentials方法是否在正确的上下文中执行。确保cubit是正确创建并执行loadStoredCredentials方法。

  4. 如果可能的话,尝试将when().thenAnswer()行移动到不同的测试用例中,以确保它们在正确的时机被调用。

  5. 检查SignInCubitState是否按预期返回。您可以尝试简化期望值,例如expect: () => true,以查看测试是否通过。

通过这些步骤,您可以逐步诊断和解决问题,以使测试能够正确运行。

英文:

Writing unit tests using mockito and the @GenerateNiceMocks annotation trying to test a cubit function, but none of the when().thenAnswer() lines seem to be working. When debugging the test and checking the local variables of that function, all of them are set to null instead of what was put in thenAnswer().

Function being tested

Future<void> loadStoredCredentials() async {
  String? email = await storage.read(key: AuthenticationKeys.rememberEmail);
  String? str = await storage.read(key: AuthenticationKeys.rememberMeKey);
  String? lastViewedMessages = await storage.read(
    key: 'lastViewedMessages',
  );

  bool rememberMe = false;
  if (str != null) {
    rememberMe = true;
  }

  if (email != null) {
    emit(state.copyWith(
      username: email,
      usernameValid: FieldValidity.valid,
      rememberMe: rememberMe,
      lastViewedMessages: lastViewedMessages,
    ));
  }
}

Test file

@GenerateNiceMocks([MockSpec<FlutterSecureStorage>()])

void main() async {
  TestWidgetsFlutterBinding.ensureInitialized();

  SignInCubit? signInCubit;

  setUp(() async {
    signInCubit = SignInCubit();
  });

  group('MockFlutterSecureStorage tests -', () {
    setUpAll(() => FlutterSecureStorage.setMockInitialValues({}));

    final email = Future.value('test@test.test');
    final flag = Future.value('true');
    final nullFuture = Future.value('');

    blocTest<SignInCubit, SignInCubitState>(
      'loadStoredCredentials - success',
      build: () => SignInCubit(),
      act: (cubit) async {
        final storage = MockFlutterSecureStorage();

        when(storage.read(key: AuthenticationKeys.rememberEmail))
            .thenAnswer((_) => email);
        when(storage.read(key: AuthenticationKeys.rememberMeKey))
            .thenAnswer((_) => flag);
        when(storage.read(key: 'lastViewedMessages'))
            .thenAnswer((_) => nullFuture);

        await cubit.loadStoredCredentials();
      },
      expect: () => (isA<SignInCubitState>),
    );
  });
}

Test error

Expected: <Closure: () => TypeMatcher<SignInCubitState> from Function 'isA': static.>
  Actual: []

package:test_api                             expect
package:bloc_test/src/bloc_test.dart 220:16  testBloc.<fn>
===== asynchronous gap ===========================
dart:async                                   _CustomZone.registerUnaryCallback
package:bloc_test/src/bloc_test.dart 201:7   testBloc.<fn>
dart:async                                   runZonedGuarded
package:bloc_test/src/bloc_test.dart 199:9   testBloc
package:bloc_test/src/bloc_test.dart 156:13  blocTest.<fn>

答案1

得分: 0

以下是您要翻译的内容:

答案是可选依赖注入。

正在测试的函数

Future<void> loadStoredCredentials({FlutterSecureStorage? storage}) async {
  FlutterSecureStorage _storage = storage ?? fSecureStorage;

  String? email = await _storage.read(
    key: AuthenticationKeys.rememberEmail,
  );
  String? str = await _storage.read(
    key: AuthenticationKeys.rememberMeKey,
  );
  String? lastViewedMessages = await _storage.read(
    key: AuthenticationKeys.lastViewed,
  );

  bool rememberMe = false;
  if (str != null) {
    rememberMe = true;
  }

  if (email != null) {
    emit(state.copyWith(
      username: email,
      usernameValid: FieldValidity.valid,
      rememberMe: rememberMe,
      lastViewedMessages: lastViewedMessages,
    ));
  }
}

通过的测试

切换到使用 mocktailx 而不是 mockito,因此语法有所改变

blocTest<SignInCubit, SignInCubitState>(
  'loadStoredCredentials - success',
  build: () => SignInCubit(),
  act: (cubit) async {
    when(() => mockStorage.read(key: AuthenticationKeys.rememberEmail))
        .thenAnswerWith('t@t.io');
    when(() => mockStorage.read(key: AuthenticationKeys.rememberMeKey))
        .thenAnswerWith('true');
    when(() => mockStorage.read(key: AuthenticationKeys.lastViewed))
        .thenAnswerWith('time');

    await cubit.loadStoredCredentials(storage: mockStorage);
  },
  expect: () => <SignInCubitState>[
    const SignInCubitState(
      username: 't@t.io',
      usernameValid: FieldValidity.valid,
      rememberMe: true,
      lastViewedMessages: 'time',
    ),
  ],
);
英文:

The answer was optional dependency injection.

Function being tested

Future<void> loadStoredCredentials({FlutterSecureStorage? storage}) async {
  FlutterSecureStorage _storage = storage ?? fSecureStorage;

  String? email = await _storage.read(
    key: AuthenticationKeys.rememberEmail,
  );
  String? str = await _storage.read(
    key: AuthenticationKeys.rememberMeKey,
  );
  String? lastViewedMessages = await _storage.read(
    key: AuthenticationKeys.lastViewed,
  );

  bool rememberMe = false;
  if (str != null) {
    rememberMe = true;
  }

  if (email != null) {
    emit(state.copyWith(
      username: email,
      usernameValid: FieldValidity.valid,
      rememberMe: rememberMe,
      lastViewedMessages: lastViewedMessages,
    ));
  }
}

Passing test

Switched to using mocktailx instead of mockito, hence syntax change

blocTest<SignInCubit, SignInCubitState>(
  'loadStoredCredentials - success',
  build: () => SignInCubit(),
  act: (cubit) async {
    when(() => mockStorage.read(key: AuthenticationKeys.rememberEmail))
        .thenAnswerWith('t@t.io');
    when(() => mockStorage.read(key: AuthenticationKeys.rememberMeKey))
        .thenAnswerWith('true');
    when(() => mockStorage.read(key: AuthenticationKeys.lastViewed))
        .thenAnswerWith('time');

    await cubit.loadStoredCredentials(storage: mockStorage);
  },
  expect: () => <SignInCubitState>[
    const SignInCubitState(
      username: 't@t.io',
      usernameValid: FieldValidity.valid,
      rememberMe: true,
      lastViewedMessages: 'time',
    ),
  ],
);

huangapple
  • 本文由 发表于 2023年5月11日 01:48:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76221300.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定