Thomas
Thomas

Reputation: 333

How to mock BLoC in Integration Test

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>?

Upvotes: 3

Views: 2970

Answers (1)

Muldec
Muldec

Reputation: 4901

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);

Upvotes: 2

Related Questions