I have a Flutter app that uses the bloc
and flutter_bloc
packages. I am trying to write an integration test using flutter_driver
and mockito
. How do I mock the BlocProvider
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>
?