mockito when().thenAnswer()在blocTest中未触发

gkl3eglg  于 2023-05-17  发布在  其他
关注(0)|答案(1)|浏览(216)

使用mockito和@GenerateNiceMocks注解编写单元测试,尝试测试一个cubit函数,但when().thenAnswer()行似乎都不起作用。在调试测试和检查该函数的局部变量时,所有这些变量都被设置为null,而不是thenAnswer()中的变量。

测试功能

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,
    ));
  }
}

测试文件

@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>),
    );
  });
}

测试错误

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>
nxowjjhe

nxowjjhe1#

答案是可选的依赖注入。

测试功能

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',
    ),
  ],
);

相关问题