[英]Flutter Bloc Test
我在一个团队中工作,我们正在使用 flutter bloc 进行 state 管理,但是我们的一个测试用例根本没有任何意义。 集团本身运作良好,但测试没有任何意义。
下面是集团本身。
import 'package:vaccify/features/logout/logout.dart';
import 'package:vaccify/features/side_navigation_bar/domain/get_user_name.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:vaccify/features/side_navigation_bar/domain/get_user_profile_pic_url.dart';
part 'auth_event.dart';
part 'auth_state.dart';
class AuthBloc extends Bloc<AuthEvent, AuthState> {
GetUserName getUserName;
GetUserProfilePic getUserProfilePic;
Logout logout;
AuthBloc(
{required this.getUserName,
required this.logout,
required this.getUserProfilePic})
: super(NotLoggedIn()) {
on<AuthLogIn>(_onLogIn);
on<AuthLogOut>(_onLogOut);
}
void _onLogIn(
AuthLogIn event,
Emitter<AuthState> emit,
) async {
final name = await getUserName();
final profilePic = await getUserProfilePic();
emit(LoggedIn(name, profilePic));
}
void _onLogOut(
AuthLogOut event,
Emitter<AuthState> emit,
) {
logout();
emit(NotLoggedIn());
}
}
现在进行测试
import 'package:bloc_test/bloc_test.dart';
import 'package:vaccify/core/bloc/authentication/auth_bloc.dart';
import 'package:vaccify/features/logout/logout.dart';
import 'package:vaccify/features/side_navigation_bar/domain/get_user_name.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:vaccify/features/side_navigation_bar/domain/get_user_profile_pic_url.dart';
class MockGetUserName extends Mock implements GetUserName {}
class MockGetProfilePicUrl extends Mock implements GetUserProfilePic {}
class MockLogout extends Mock implements Logout {}
void main() {
late AuthBloc authBloc;
late MockGetUserName mockGetUserName;
late MockLogout mockLogout;
late MockGetProfilePicUrl mockGetProfilePicUrl;
setUp(() {
mockGetUserName = MockGetUserName();
mockLogout = MockLogout();
mockGetProfilePicUrl = MockGetProfilePicUrl();
authBloc = AuthBloc(
getUserName: mockGetUserName,
logout: mockLogout,
getUserProfilePic: mockGetProfilePicUrl);
});
/// Contains bloc tests for the [AuthBloc] class
group(
'AuthBloc',
() {
/// Tests that a [LoggedIn] state occurs when the [AuthLogIn] is called.
blocTest(
'login',
build: () {
when(() => mockGetUserName()).thenAnswer((_) async => "Hello");
when(() => mockGetProfilePicUrl()).thenAnswer((_) async => "");
return authBloc;
},
act: (AuthBloc bloc) {
bloc.add(AuthLogIn());
},
expect: () => [isA<LoggedIn>()],
);
/// Tests that a [NotLoggedIn] state occurs when the [AuthLogOut] is called.
blocTest(
'logout',
build: () {
when(() => mockGetUserName()).thenAnswer((_) async => "John Smith");
when(() => mockGetProfilePicUrl()).thenAnswer((_) async => "");
when(() => mockLogout()).thenAnswer((_) async {});
return authBloc;
},
act: (AuthBloc bloc) {
bloc.add(AuthLogIn());
bloc.add(AuthLogOut());
},
expect: () => [
isA<LoggedIn>(),
isA<NotLoggedIn>(),
],
);
},
);
}
第一个测试“登录”工作正常并通过,因为我们添加了一个事件“AuthLogin()” ,然后我们期望LoggedIn state
第二个测试“注销”是问题所在,因为我们添加了两个事件AuthLogin() 和 AuthLogOut() ,因为您必须登录才能注销。 然后我们分别期望LoggedIn 和 NotLoggedIn状态。
测试失败并显示以下消息
预期:[<<“LoggedIn”实例>>,<<“NotLoggedIn”实例>>]
实际:['NotLoggedIn' 实例,'LoggedIn' 实例]
有趣的是,当我们交换两者时,期望测试通过......如下所示
expect: () => [
isA<NotLoggedIn>(),
isA<LoggedIn>(),
],
任何建议或指导将不胜感激。
谢谢大家
如果您添加AuthLogIn
事件只是为了为第二个事件准备您的 bloc,那么您可以使用来自blocTest
的seed
。 像这样的东西:
blocTest(
'logout',
build: () {
when(() => mockLogout()).thenAnswer((_) async {});
return authBloc;
},
seed: () => LoggedIn(),
act: (AuthBloc bloc) {
bloc.add(AuthLogOut());
},
expect: () => [
isA<NotLoggedIn>(),
],
);
关于您的问题,我认为在添加两个事件之间使用延迟( await Future.delayed(Duration(seconds: 1))
)将解决它。 请注意, Bloc
默认情况下同时转换事件,在您的情况下,首先处理注销(它比登录功能完成得更快),然后处理您的登录事件,这会导致问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.