【问题标题】:Flutter: how to mock BlocFlutter:如何模拟 Bloc
【发布时间】:2019-08-09 16:42:26
【问题描述】:

我想模拟我的 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);
    }
  }
}

这是视图:

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

现在,这是我的测试:

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

如你所见,我只是想测试一下,当用户在搜索中写了一些东西,并且他正在寻找的对象存在时,应该显示一张卡片。

【问题讨论】:

  • 您找到了实现这一目标的方法吗?

标签: testing flutter mocking bloc


【解决方案1】:

查看来自 David Anaya 的帖子,该帖子涉及使用“Bloc”和 mockito 进行单元测试。

他的例子的最后一个版本是here

【讨论】:

  • david anaya 正在测试 blocs,这个问题是如何通过模拟 blocs 来测试小部件
【解决方案2】:

有时小部件需要一点时间来构建。尝试:

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

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

【讨论】:

    【解决方案3】:

    如果我理解正确,您是在模拟 searchBloc 使用的某些服务。我个人尝试以一种应用程序仅依赖于一个 bloc 并且 bloc 可能依赖于其他一些服务的方式来设计应用程序。然后当我想做一个小部件测试时,我只需要模拟这个 bloc。您可以为此使用bloc_test 包。

    在 bloc_test 页面上有这个示例用于存根 counterBloc:

    // Create a mock instance
    final counterBloc = MockCounterBloc();
    
    // Stub the bloc `Stream`
    whenListen(counterBloc, Stream.fromIterable([0, 1, 2, 3]));
    

    但是,我通常不需要存根 bloc 流,并且像这样发出状态就足够了

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

    希望这会有所帮助。

    【讨论】:

      【解决方案4】:

      要模拟该集团,您可以使用bloc_test package

      此外,您还可以观看 this tutorial,其中涵盖了 bloc 测试,包括非常不错的 mock bloc。

      【讨论】:

        猜你喜欢
        • 2019-02-07
        • 2019-06-13
        • 2019-11-25
        • 2021-03-19
        • 2019-07-19
        • 1970-01-01
        • 2019-05-23
        • 2020-08-16
        • 2020-11-07
        相关资源
        最近更新 更多