So I have a requirement where I need to test my widget’s UI as perfect as possible. I am using clean architecture with Bloc pattern, but keep failing some of my test cases.
In some cases, where I emit a loading state and my loader dialog is visible and then when I emit a success state my success UI should be build, I am not finding my widget from my testcase.
In UI, all is running fine.
I have two questions,
In my testcase, how can I emit multiple states from my mock cubit?
In debugging of my testcase, it only goes to BlocBuilder widget(probably because it is still in initial loading state). In that case, how can I make my testcase test or go through the listener flow too.
This is the example code of flutter widget testing here
testWidgets('renders WeatherPopulated for WeatherStatus.success',
(tester) async {
when(() => weatherCubit.state).thenReturn(
WeatherState(
status: WeatherStatus.loading,
),
);
await tester.pumpWidget(
BlocProvider.value(
value: weatherCubit,
child: MaterialApp(home: WeatherView()),
),
);
expect(find.byType(WeatherLoading), findsOneWidget);
when(() => weatherCubit.state).thenReturn(
WeatherState(
status: WeatherStatus.success,
weather: weather,
),
);
await tester.pumpWidget(
BlocProvider.value(
value: weatherCubit,
child: MaterialApp(home: WeatherView()),
),
);
tester.binding.scheduleWarmUpFrame();
// debugDumpApp();
// Trigger a rebuild
await tester.pump();
// Debugging output
debugPrint('Current state: ${weatherCubit.state}');
expect(find.byType(WeatherLoading), findsNothing);
expect(find.byType(WeatherPopulated), findsOneWidget);
});
This throws the error
The following TestFailure was thrown running a test:
Expected: no matching candidates Actual: _TypeWidgetFinder:<Found 1 widget with type "WeatherLoading": [
WeatherLoading(dependencies: [_InheritedTheme, _LocalizationsScope-[GlobalKey#4a927]]),
]>
Which: means one was found but none were expected