简体   繁体   English

BlocBuilder 小部件的 Flutter 小部件测试

[英]Flutter Widget Testing for BlocBuilder Widgets

I have a Widget which uses bloc builder to map the different state of widget.我有一个小部件,它使用块构建器来 map 小部件的不同 state。

class BodyWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return BlocBuilder<NewsBloc, NewsState>(builder: (context, state) {
          return state.map(
            .....
          );
        });
      }
    ....
    }

The BodyWidget is created in a Widget with BlocProvider. BodyWidget是在一个带有 BlocProvider 的 Widget 中创建的。

class MainPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) =>
          getIt<NewsBloc>()..add(const NewsEvent.fetchNewsData()),
      child: BodyWidget(),
    );
  }
....
}

And the NewsBloc is defined as NewsBloc 被定义为

@injectable
class NewsBloc extends Bloc<NewsEvent, NewsState> {
  final GetNews getNews;
  NewsBloc({
    @required this.getNews,
  }) : super(const _Initial());

  @override
  Stream<NewsState> mapEventToState(
    NewsEvent event,
  ) async* { ... }
}

I am using get_it and injectable for Dependency Injection.我正在使用get_it和 injectionable 进行依赖注入

Now I am trying to write a simple widget test for BodyWidget and I am not so sure how to inject all these dependency in test.现在我正在尝试为BodyWidget编写一个简单的小部件测试,但我不太确定如何在测试中注入所有这些依赖项。

class MockBuildContext extends Mock implements BuildContext {}

class MockNewsBloc extends Mock implements NewsBloc {}

void main() {
  ForYouNewsTab _widget;
  MockBuildContext _context;
  NewsBloc _newsBloc;

  Widget makeTestableWidgets({Widget child}) {
    return MaterialApp(
      home: Scaffold(
        // body: BlocProvider(
        //   create: (_context) => getIt<NewsBloc>(),
        //   child: child,
        // ),
        body: child,
      ),
    );
  }

  setUp(() {
    _context = MockBuildContext();
    _widget = ForYouNewsTab();
  });

  test('ForYouNewsTab is sub class of StatelessWidget', () {
    expect(_widget, isA<StatelessWidget>());
  });

  testWidgets('should return sized box for initial state',
      (WidgetTester tester) async {
    await tester.pumpWidget(makeTestableWidgets(child: _widget));
  });
}

I did search in stackoverflow, but could not found a solution that works form me.我确实在 stackoverflow 中进行了搜索,但找不到适合我的解决方案。

I solved my issue by following very basic steps.我按照非常基本的步骤解决了我的问题。 Not so sure if its the right way.不太确定它是否正确。 Anyway if anyone ever comes to the same problem, it might help them.无论如何,如果有人遇到同样的问题,它可能会对他们有所帮助。

class MainPage extends StatelessWidget {

  //added line
  final NewsBloc newsBloc;

  const MainPage({
    Key key, 
    @required this. newsBloc,
  })

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      // changed line
      // create: (context) => getIt<NewsBloc>()..add(const NewsEvent.fetchNewsData()),
      create: (context) => newsBloc..add(const NewsEvent.fetchNewsData()),
      child: BodyWidget(),
    );
  }

  ....

 }

Now in my test case I can create MockNewsBloc and inject it easily to the MainPage when it is under testing.现在在我的测试用例中,我可以创建 MockNewsBloc 并在测试时将其轻松注入 MainPage。

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

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