0

我正在尝试使用 bloc_test 库进行单元测试。

这是我的代码。

登录肘

class LoginCubit extends Cubit<LoginState> with HydratedMixin {
  final UserRepository _userRepository;
  LoginCubit(this._userRepository) : super(LoginInitial());

  Future<void> login (String email, String password , bool remember) async {
    bool result = await _userRepository.isLoginCorrectWithEmailAndPassword(email, password);
    if (result){
      emit(LoggedIn(remember: remember, email: email));
    } else {
      emit(LoginError());
    }
  }
}

登录状态

part of 'login_cubit.dart';

@immutable
abstract class LoginState extends Equatable {}

class LoginInitial extends LoginState {
  final bool remember;
  final String email;
  LoginInitial({this.remember = false, this.email = ''});

  @override
  List<Object?> get props => [remember, email];
}

class LoggedIn extends LoginState {
  final bool remember;
  final String email;
  LoggedIn({required this.remember, required this.email});

  @override
  List<Object?> get props => [remember, email];
}

class LoginError extends LoginState {
  LoginError();

  @override
  List<Object?> get props => [];
}

单元测试

class MockUserRepository extends Mock implements UserRepository {
  @override
  Future<bool> isLoginCorrectWithEmailAndPassword(String email, String password) {
    return Future.value(true);
  }
}

void main() {
  group('LoginCubit', () {
    late LoginCubit loginCubit;

    setUp(() {
      loginCubit = LoginCubit(MockUserRepository());
    });

    tearDown(() {
      loginCubit.close();
    });

    test('the initial state value is LoginInitial', () {
      expect(loginCubit.state, LoginInitial());
    });

    blocTest<LoginCubit, LoginState>(
      'TODO: description',
      build: () => loginCubit,
      act: (cubit) => cubit.login("any email", "any password", true),
      expect: () => <LoginState>[
        LoggedIn(remember: true, email: "any email"),
      ],
    );
  });
}

我的问题是第二个测试总是返回一个空数组。通过一些打印,我确信代码正在发出 LoggedIn 状态,但测试实际上无法识别它。

我在哪里犯了错误?:)

4

2 回答 2

0

您忘记为存储库函数调用添加存根。

  1. 从 Mock 类创建一个对象MockUserRepository repo = MockUserRepository();

  2. 像这样将这个对象传递给函数LoginCubit中的setUp

    setUp(() { loginCubit = LoginCubit(repo); });

  3. 将此行添加到act测试中的函数

        when(repo.isLoginCorrectWithEmailAndPassword(any, any)).thenAnswer((_) async => true);
    

所以整个测试应该是这样的

blocTest<LoginCubit, LoginState>(
  'TODO: description',
  build: () => loginCubit,
  act: (cubit) {
      when(repo.isLoginCorrectWithEmailAndPassword(any, any)).thenAnswer((_) async => true);
      cubit.login("any email", "any password", true);
  },
  expect: () => <LoginState>[
    LoggedIn(remember: true, email: "any email"),
  ],
);
于 2021-12-22T02:40:35.110 回答
0

问题是我在测试中使用了 Hydrated Bloc 而没有对其进行初始化。这是解决方案: https ://github.com/felangel/bloc/issues/2022#issuecomment-747918417

于 2021-12-24T12:40:22.790 回答