Flutter Bloc测试中Mockito的when方法报错:无方法存根被调用
解决Mockito
when() 调用错误的方案 错误原因分析
你遇到的Bad state: No method stub was called from within when()错误,核心来自两个问题:
- 对Bloc的
stategetter存根时,返回值错误地写成了函数而非WeatherState实例 - 未注册Bloc事件/状态的fallback值,导致Mockito无法正确处理Bloc内部的类型匹配
修复步骤
1. 修正when()的存根写法
把返回函数的写法改成直接返回WeatherEmpty实例,这是触发错误的直接原因:
// 错误写法 when(() => mockWeatherBloc.state).thenReturn(() => WeatherEmpty()); // 正确写法 when(() => mockWeatherBloc.state).thenReturn(WeatherEmpty());
2. 注册Fallback值
在main函数开头添加setUpAll,注册事件和状态的fallback值,确保Mockito能正确处理Bloc的交互逻辑:
void main() { late MockWeatherBloc mockWeatherBloc; setUpAll(() { registerFallbackValue(FakeWeatherEvent()); registerFallbackValue(FakeWeatherState()); }); setUp(() => mockWeatherBloc = MockWeatherBloc()); // ... 其余代码保持不变 }
3. 完善测试逻辑(贴合你的测试目标)
如果要验证输入文本后状态从Empty变为Loading,需要补充事件监听和状态断言逻辑:
testWidgets( 'text field trigger state to change from empty to loading', (widgetTester) async { // Arrange when(() => mockWeatherBloc.state).thenReturn(WeatherEmpty()); // 模拟Bloc接收事件后发出Loading状态 whenListen( mockWeatherBloc, Stream.fromIterable([ WeatherEmpty(), WeatherLoading(), ]), ); // Act await widgetTester.pumpWidget(makeTestableWidget(const WeatherPage())); final textField = find.byType(TextField); expect(textField, findsOneWidget); await widgetTester.enterText(textField, 'Karachi'); // 触发文本提交(假设输入完成后会触发提交动作) await widgetTester.testTextInput.receiveAction(TextInputAction.done); await widgetTester.pumpAndSettle(); // Assert expect(find.text('Karachi'), findsOneWidget); // 验证Bloc是否收到了获取天气的事件 verify(mockWeatherBloc.add(GetWeatherEvent('Karachi'))).called(1); // 验证状态是否切换为Loading expect(mockWeatherBloc.state, isA<WeatherLoading>()); }, );
4. 确保依赖版本兼容
检查pubspec.yaml中的依赖版本,保证mockito、bloc_test和flutter_bloc版本匹配,示例配置:
dev_dependencies: flutter_test: sdk: flutter mockito: ^5.4.0 bloc_test: ^9.1.0 flutter_bloc: ^8.1.3
内容的提问来源于stack exchange,提问作者Usman Khan
相关产品推荐
相关产品推荐

