Flutter Bloc 单元测试 return 一个空数组
Flutter Bloc Unit Test return an empty array
我正在尝试使用 bloc_test 库进行单元测试。
这是我的代码。
登录Cubit
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"),
],
);
});
}
我的问题是第二个测试 return 总是一个空数组。
通过一些打印,我确定代码正在发出 LoggedIn 状态,但测试实际上无法识别它。
我哪里弄错了? :)
您忘记为存储库函数调用添加存根。
从 Mock 创建对象 Class MockUserRepository repo = MockUserRepository();
像这样将这个对象传递给setUp
函数中的LoginCubit
setUp(() { loginCubit = LoginCubit(repo); });
将这一行添加到测试中的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"),
],
);
问题是我在测试中使用了 Hydrated Bloc 而没有对其进行初始化。
这是它的解决方案:
https://github.com/felangel/bloc/issues/2022#issuecomment-747918417
我正在尝试使用 bloc_test 库进行单元测试。
这是我的代码。
登录Cubit
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"),
],
);
});
}
我的问题是第二个测试 return 总是一个空数组。 通过一些打印,我确定代码正在发出 LoggedIn 状态,但测试实际上无法识别它。
我哪里弄错了? :)
您忘记为存储库函数调用添加存根。
从 Mock 创建对象 Class
MockUserRepository repo = MockUserRepository();
像这样将这个对象传递给
setUp
函数中的LoginCubit
setUp(() { loginCubit = LoginCubit(repo); });
将这一行添加到测试中的
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"),
],
);
问题是我在测试中使用了 Hydrated Bloc 而没有对其进行初始化。 这是它的解决方案: https://github.com/felangel/bloc/issues/2022#issuecomment-747918417