如何在集成测试中模拟BLoC

时间:2019-07-30 13:41:34

标签: unit-testing flutter mocking integration-testing bloc

我有一个Flutter应用,它使用blocflutter_bloc软件包。我正在尝试使用flutter_drivermockito编写集成测试。如何模拟BlocProvider及其子项以始终发出一个模拟状态?

原始集团:

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

我尝试过嘲弄集团并覆盖state吸气剂:

class MockSummaryBloc extends Mock implements SummaryBloc {}

然后在已检测的应用程序中使用Mockito:

final MockSummaryBloc summaryBloc = MockSummaryBloc();

// whenever the state stream getter is called, return the mocked stream.
when(summaryBloc.state).thenAnswer((_) async* {
    yield BlocStateSuccess<Summary>(mockSummary);
  });

出于良好的考虑,我为initialState尝试了相同的操作。

要在检测的应用中使用模拟,我使用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'}');
        },
      )),
    ),
  ));

我希望文本小部件在运行时打印BlocStateSuccess<Summary>。但是,在驱动程序测试的生命周期内,该状态为null。

我错误地嘲笑了这个集团吗?还有其他模拟Bloc或Stream<BlocState>的方法吗?

1 个答案:

答案 0 :(得分:0)

您应该尝试模拟SummaryRepository而不是集团。这将使您能够测试块的行为,并控制存储库返回到流的内容。

class MockSummaryRepository extends Mock implements SummaryRepository{}

var mockRepository = MockSummaryRepository();
when(mockRepository.getSummary()).thenReturn(mockSummary);

final SummaryBloc summaryBloc = SummaryBloc(mockRepository);