Flutter bloc_test中Cubit状态不更新的问题及解决方法
解决Bloc测试中Mock Cubit状态不更新的问题
问题原因
你定义的MockAuth是基于MockBloc的模拟类,它只会实现Bloc/Cubit的基础生命周期方法,但自定义的setEmail方法默认是空实现,调用后不会触发emit动作,自然不会更新状态。而真实的AuthCubit里setEmail有明确的emit(state.copyWith(...))逻辑,所以替换后能正常工作。
解决方案
方案1:用Mockito指定Mock方法的行为
通过when()方法模拟setEmail调用时的逻辑,让它主动emit目标状态:
import 'package:mockito/mockito.dart'; class MockAuth extends MockBloc<AuthCubit, AuthState> implements AuthCubit {} void main() { blocTest( '调用setEmail后更新邮箱状态', build: () { final mockAuth = MockAuth(); // 模拟setEmail方法:调用时emit包含传入邮箱的新状态 when(() => mockAuth.setEmail(any())).thenAnswer((invocation) { final targetEmail = invocation.positionalArguments[0] as String; mockAuth.emit(AuthState( email: targetEmail, password: "", firstName: "", lastName: "", genderUuid: "", ageGroupUuid: "", countryUuid: "", forgotEmail: "", code: 0, )); return; }); return mockAuth; }, act: (bloc) => bloc.setEmail("secret@email.com"), expect: () => [ const AuthState( email: "secret@email.com", password: "", firstName: "", lastName: "", genderUuid: "", ageGroupUuid: "", countryUuid: "", forgotEmail: "", code: 0, ) ] ); }
方案2:用Fake类实现真实方法逻辑
如果希望模拟类保留AuthCubit的真实业务逻辑,可以用Fake类实现自定义方法:
import 'package:mockito/mockito.dart'; class FakeAuth extends Fake implements AuthCubit { AuthState _state = const AuthState( email: "", password: "", firstName: "", lastName: "", genderUuid: "", ageGroupUuid: "", countryUuid: "", forgotEmail: "", code: 0, ); @override AuthState get state => _state; @override void emit(AuthState newState) { _state = newState; super.emit(newState); } @override void setEmail(String email) => emit(_state.copyWith(email: email)); } void main() { blocTest( '调用setEmail后更新邮箱状态', build: () => FakeAuth(), act: (bloc) => bloc.setEmail("secret@email.com"), expect: () => [ const AuthState( email: "secret@email.com", password: "", firstName: "", lastName: "", genderUuid: "", ageGroupUuid: "", countryUuid: "", forgotEmail: "", code: 0, ) ] ); }
注意事项
- 确保
AuthState的copyWith方法正确实现所有字段的复制逻辑,否则状态更新会出现异常(你用真实Cubit正常,说明这部分没问题) - 如果使用Mockito的代码生成(
@GenerateMocks注解),需要先运行flutter pub run build_runner build生成对应的mock类
内容的提问来源于stack exchange,提问作者newbie2210
相关产品推荐
相关产品推荐

