如何在blocTest中验证WeatherLoading状态并忽略后续任意状态?
如何在blocTest中仅验证指定状态,忽略后续状态?
问题背景
现有如下blocTest测试代码:
blocTest( 'emits [WeatherLoading, WeatherLoaded] when successful', build: () { when(mockWeatherRepository.fetchWeather(any)) .thenAnswer((_) async => weather); return WeatherBloc(mockWeatherRepository); }, act: (bloc) => bloc.add(GetWeather('London')), expect: [WeatherInitial(), WeatherLoading(), WeatherLoaded(weather)], );
需要编写新测试用例:仅验证WeatherLoading状态被发射,对其之后的状态(如WeatherLoaded或其他)不做要求,期望实现类似在expect中添加AnyState的效果。
解决方案
有三种常用方法可以实现需求:
1. 使用predicate匹配任意后续状态
在expect数组的末尾添加一个始终返回true的断言函数,即可匹配任意后续状态:
blocTest( '验证WeatherLoading状态被发射', build: () { when(mockWeatherRepository.fetchWeather(any)) .thenAnswer((_) async => weather); return WeatherBloc(mockWeatherRepository); }, act: (bloc) => bloc.add(GetWeather('London')), expect: [ WeatherInitial(), WeatherLoading(), predicate((state) => true), // 匹配任意后续状态 ], );
这种方式会严格验证前两个状态的顺序和类型,第三个位置的状态可以是任意值,完全符合需求。
2. 使用verify回调检查状态历史
如果只关心WeatherLoading是否被发射,不严格要求前面的状态顺序,可以直接在verify回调中检查bloc的状态历史:
blocTest( '验证WeatherLoading状态被发射', build: () { when(mockWeatherRepository.fetchWeather(any)) .thenAnswer((_) async => weather); return WeatherBloc(mockWeatherRepository); }, act: (bloc) => bloc.add(GetWeather('London')), verify: (bloc) { // 检查状态历史中存在WeatherLoading expect(bloc.stateHistory.contains(WeatherLoading()), isTrue); // 可选:验证WeatherLoading出现在WeatherInitial之后 final loadingIndex = bloc.stateHistory.indexOf(WeatherLoading()); final initialIndex = bloc.stateHistory.indexOf(WeatherInitial()); expect(loadingIndex > initialIndex, isTrue); }, );
这种方式更灵活,适合需要自定义验证逻辑的场景。
3. 使用expectLater监听状态流(底层方式)
如果需要更精细的状态监听控制,可以直接使用expectLater配合emitsThrough:
test('验证WeatherLoading状态被发射', () async { when(mockWeatherRepository.fetchWeather(any)) .thenAnswer((_) async => weather); final bloc = WeatherBloc(mockWeatherRepository); // 监听状态流,直到捕获到WeatherLoading await expectLater( bloc.stream, emitsThrough(WeatherLoading()), ); bloc.add(GetWeather('London')); await bloc.close(); });
这种方式绕过了blocTest的封装,直接操作bloc的状态流,适合复杂的测试场景。
内容的提问来源于stack exchange,提问作者Yukinosuke Takada
相关产品推荐
相关产品推荐

