如何在集成测试中模拟 BLoC
Posted
技术标签:
【中文标题】如何在集成测试中模拟 BLoC【英文标题】:How to mock BLoC in Integration Test 【发布时间】:2019-12-07 22:26:05 【问题描述】:我有一个使用 bloc
和 flutter_bloc
包的 Flutter 应用程序。我正在尝试使用flutter_driver
和mockito
编写集成测试。如何模拟 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
getter:
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'');
,
)),
),
));
我希望 Text 小部件在运行时打印 BlocStateSuccess<Summary>
。但是,在驱动程序测试的生命周期内,该状态为空。
我是不是在错误地嘲笑这个集团?还有其他模拟 Bloc 或 Stream<BlocState>
的方法吗?
【问题讨论】:
能否提供SummaryBloc类的定义? 谢谢,已添加。 SummaryRepository 实现应该不是必需的,所以我把它省略了。 谢谢。MockSummaryBloc
的定义是什么?
【参考方案1】:
您应该尝试模拟 SummaryRepository
而不是 Bloc。这将允许您测试 bloc 的行为并控制存储库返回到流的内容。
class MockSummaryRepository extends Mock implements SummaryRepository
var mockRepository = MockSummaryRepository();
when(mockRepository.getSummary()).thenReturn(mockSummary);
final SummaryBloc summaryBloc = SummaryBloc(mockRepository);
【讨论】:
以上是关于如何在集成测试中模拟 BLoC的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Flutter 集成测试中最好地存根/模拟 rest API 调用