【问题标题】:Flutter Widget Testing for BlocBuilder WidgetsBlocBuilder 小部件的 Flutter 小部件测试
【发布时间】:2021-05-09 16:15:26
【问题描述】:

我有一个小部件,它使用 bloc 构建器来映射小部件的不同状态。

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_itinjectable 进行依赖注入。

现在我正在尝试为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 中进行了搜索,但找不到适合我的解决方案。

【问题讨论】:

    标签: flutter testing dependency-injection bloc widget-test-flutter


    【解决方案1】:

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

    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。

    【讨论】:

      猜你喜欢
      • 2019-02-25
      • 2019-05-23
      • 2022-12-12
      • 2019-06-13
      • 2019-06-11
      • 2020-03-21
      • 2021-09-22
      • 2021-02-04
      • 2021-05-14
      相关资源
      最近更新 更多