简体   繁体   English

Flutter:如何模拟 Bloc

[英]Flutter: how to mock Bloc

I would like to mock my Bloc in order to test my view.我想模拟我的集团以测试我的观点。

For example, this is my Bloc:例如,这是我的 Bloc:

class SearchBloc extends Bloc<SearchEvent, SearchState> {
  @override
  // TODO: implement initialState
  SearchState get initialState => SearchStateUninitialized();

  @override
  Stream<SearchState> mapEventToState(SearchState currentState, SearchEvent event) async* {
    if (event is UserWrites) {
      yield (SearchStateInitialized.success(objects);
    }
  }
}

And this is the view:这是观点:

class _SearchViewState extends State<SearchView> {
  final TextEditingController _filterController = new TextEditingController();

  @override
  void initState() {
    _filterController.addListener(() {
    widget._searchBloc.dispatch(FetchByName(_filterController.text));
     }
  }


 TextField buildAppBarTitle(BuildContext context) {
    return new TextField(
      key: Key("AppBarTextField"),
        controller: _filterController,
    );
  }

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: buildAppBarTitle(context),),
      body: buildBlocBuilder(),
    );
  }

BlocBuilder<SearchEvent, SearchState> buildBlocBuilder() {
    return BlocBuilder(
        bloc: widget._searchBloc,
        builder: (context, state) {
          if (state is SearchStateUninitialized) {
            return Container(
              key: Key("EmptyContainer"),
            );
          } 
            return buildInitializedView(state, context);
          }
        });

buildInitializedView(SearchStateInitialized state, BuildContext context) {
    if (state.objects.isEmpty) {
      return Center(child: Text("Nothing found"),);
    } else {
      return buildListOfCards();
    }
  }
    }

Now, this is my test:现在,这是我的测试:

testWidgets('Should find a card when the user searches for something', (WidgetTester tester) async {

  _searchView = new SearchView(_searchBloc);

    when(mockService.find( name: "a")).thenAnswer((_) =>
    [objects]);

    await tester.pumpWidget(generateApp(_searchView));
    await tester.enterText(find.byKey(Key("searchBar")), "a");
    await tester.pump();

    expect(find.byType(Card), findsOneWidget);
  });
}

As you can see, I just want to test that, when the user writes something in the search, and the object he's looking for exists, a card should be shown.如您所见,我只是想测试一下,当用户在搜索中写入内容并且他正在寻找的对象存在时,应该显示一张卡片。

If I understood correctly, you are mocking some service that is used by the searchBloc.如果我理解正确,您是在嘲笑 searchBloc 使用的某些服务。 I personally try to design the app in a way that the app only depends on a bloc and the bloc may depend on some other services.我个人尝试以一种应用程序仅依赖于一个集团而该集团可能依赖于其他一些服务的方式来设计该应用程序。 Then when I would like to make a widget test, I only need to mock the bloc.然后当我想做一个小部件测试时,我只需要模拟 bloc。 You can use bloc_test package for that.您可以为此使用bloc_test包。

There is this example on the bloc_test page for stubbing a counterBloc: bloc_test 页面上有一个用于存根 counterBloc 的示例:

// Create a mock instance
final counterBloc = MockCounterBloc();

// Stub the bloc `Stream`
whenListen(counterBloc, Stream.fromIterable([0, 1, 2, 3]));

however, I often do not need to stub the bloc stream and it is enough to emit the state, like this然而,我通常不需要存根 bloc 流,它足以发出状态,像这样

when(counterBloc.state).thenAnswer((_) => CounterState(456));

Hope this helps.希望这可以帮助。

Have a look at a post from David Anaya which deal with Unit Testing with “Bloc” and mockito.看一看David Anaya的帖子,该帖子涉及使用“Bloc”和 mockito 进行单元测试。

The last version of his example is here他的例子的最后一个版本在这里

Sometimes widgets require a little time to build.有时小部件需要一点时间来构建。 Try with:尝试:

await tester.pumpWidget(generateApp(_searchView));
await tester.enterText(find.byKey(Key("searchBar")), "a");
await tester.pump(Duration(seconds: 1));

expect(find.byType(Card), findsOneWidget);

To mock the bloc, you can use the bloc_test package要模拟 bloc,您可以使用bloc_test 包

Also, you may watch this tutorial which covers bloc testing include mock bloc very nice.此外,您可以观看本教程,其中涵盖了 bloc 测试,包括模拟 bloc 非常好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM