繁体   English   中英

BlocBuilder 小部件的 Flutter 小部件测试

[英]Flutter Widget Testing for BlocBuilder Widgets

我有一个小部件,它使用块构建器来 map 小部件的不同 state。

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

BodyWidget是在一个带有 BlocProvider 的 Widget 中创建的。

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

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* { ... }
}

我正在使用get_it和 injectionable 进行依赖注入

现在我正在尝试为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));
  });
}

我确实在 stackoverflow 中进行了搜索,但找不到适合我的解决方案。

我按照非常基本的步骤解决了我的问题。 不太确定它是否正确。 无论如何,如果有人遇到同样的问题,它可能会对他们有所帮助。

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

  ....

 }

现在在我的测试用例中,我可以创建 MockNewsBloc 并在测试时将其轻松注入 MainPage。

暂无
暂无

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

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