How to mock BLoC in Integration Test
You should try to mock SummaryRepository
instead of the Bloc. That will allow you to test the behavior of the bloc and keeping control of what the repository returns to the stream.
class MockSummaryRepository extends Mock implements SummaryRepository{}
var mockRepository = MockSummaryRepository();
when(mockRepository.getSummary()).thenReturn(mockSummary);
final SummaryBloc summaryBloc = SummaryBloc(mockRepository);
Thomas
Updated on December 13, 2022Comments
-
Thomas over 1 year
I have a Flutter app that uses the
bloc
andflutter_bloc
packages. I am trying to write an integration test usingflutter_driver
andmockito
. How do I mock theBlocProvider
and its children to always emit a single mocked state?The original bloc:
class SummaryBloc extends Bloc<BlocEvent, BlocState> { final SummaryRepository repository; SummaryBloc(this.repository); @override BlocState<Summary> get initialState => BlocStateEmpty<Summary>(); @override Stream<BlocState> mapEventToState( BlocEvent event, ) async* { if (event is Fetch) yield BlocStateSuccess<Summary>(repository.getSummary()); } }
I have tried mocking the bloc and overriding the
state
getter:class MockSummaryBloc extends Mock implements SummaryBloc {}
Then using mockito in the instrumented app:
final MockSummaryBloc summaryBloc = MockSummaryBloc(); // whenever the state stream getter is called, return the mocked stream. when(summaryBloc.state).thenAnswer((_) async* { yield BlocStateSuccess<Summary>(mockSummary); });
For good measure I have tried the same for
initialState
.To use the mock in the instrumented app, I use
BlocProvider.value
:runApp(BlocProvider.value( value: summaryBloc, child: MaterialApp( title: 'Test Driver', home: Scaffold( body: BlocBuilder( bloc: summaryBloc, // the builder rebuilds on state change. builder: (context, state) { return Text('state: ${state?.runtimeType ?? 'isNull'}'); }, )), ), ));
I expect the Text widget to print
BlocStateSuccess<Summary>
during runtime. However, the state is null during the lifespan of the driver test.Am I incorrectly mocking this Bloc? Are there other methods of mocking a Bloc, or
Stream<BlocState>
?