Flutter Bloc Widget 测试如何在 bloc 模式中的 If 语句下 find.text

Flutter Bloc Widget testing how to find.text under If statement in bloc pattern

我正在尝试使用 Widget 测试我的 WelcomeScreen()。 WelcomeScreen 有一个 BlocProvider 和一个 BlocBuilder。在我加载 WelcomeBloc() 之后,它会检查构建器中的 if 语句以检查状态是否为 WelcomeLoadSuccessState。

如果语句为真,我如何在 if 语句下找到内容?

我的欢迎屏幕:

Widget build(BuildContext context) {
  return BlocProvider(
   create: (context) => WelcomeBloc(),
   child: BlocBuilder<WelcomeBloc, WelcomeState>(
     builder: (context, state) {
       if (state is WelcomeLoadSuccessState) {
         return Scaffold(
           body: Container(
            child: Column(
              children: [
                Wrap(
                  direction: Axis.vertical,
                  crossAxisAlignment: WrapCrossAlignment.center,
                  children: [
                    Padding(
                      padding: EdgeInsets.all(8),
                      child: ShowUp(
                          delay: _delay + 200,
                          child: Text('Welcome user’,        // <——— I want to find this one
                              )),
                    ),
                  
                  ],
                ),
              ],
            )),
      );
    }

    // return LoadingWidget();
    return Text('Something');       // <——— This one I can find
  },
),
);
}

我现在的测试:

    main() {
  WelcomeBloc welcomeBloc;
  WelcomeService welcomeService;
  final Brand brand = Brand();

  setUp(() {
    setUpMocks();
    welcomeService = localServices<WelcomeService>();
    welcomeBloc = MockWelcomeBloc();
  });

 _createWidget(WidgetTester tester) async {
    when(welcomeService.getBrand(id: '609a88d324a01928242d1ca9')).thenAnswer((realInvocation) => Future.value(brand));
    welcomeBloc.add(WelcomeLoadRequestEvent(id: '609a88d324a01928242d1ca9'));
    when(welcomeBloc.state).thenAnswer((_) => WelcomeLoadSuccessState(brand: brand));

    print(welcomeBloc.state); //Correct State (WelcomeLoadSuccessState)

    await tester.pumpWidget(
        MaterialApp(
          title: 'Flutter Demo',
          home: WelcomeScreen(),
        )
    );

    await tester.pump();
  }

  testWidgets('Welcome Screen Test', (WidgetTester tester) async {
    await _createWidget(tester);
    await tester.pump();

    //expect(find.textContaining('Welcome user'), findsOneWidget); //What I want
    expect(find.text('Something'), findsOneWidget);  //This works
  });

  tearDown(() {
    welcomeBloc?.close();
  });
}

感谢您的帮助。

我解决了:

变化:

create: (context) => WelcomeBloc()

至:

create: (context) => WelcomeBloc()..add(WelcomeLoadRequestEvent(id: '609a88d324a01928242d1ca9')),

现在我的测试是这样的:

main() {
  WelcomeBloc welcomeBloc;
  WelcomeService welcomeService;
  final Brand brand = Brand();

  setUp(() {
    setUpMocks();
    welcomeService = localServices<WelcomeService>();
    welcomeBloc = MockWelcomeBloc();
  });

  _createWidget(WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(
      title: 'Flutter Demo',
      home: WelcomeScreen(),
    ));

   await tester.pump(Duration(seconds: 10));
  }

  testWidgets('Welcome Screen Test', (WidgetTester tester) async {
    when(welcomeService.getBrand(id: '609a88d324a01928242d1ca9'))
        .thenAnswer((realInvocation) => Future.value(brand));
    whenListen(
        welcomeBloc,
        Stream.fromIterable([
      WelcomeLoadInProgressState(),
      WelcomeLoadSuccessState(brand: brand),
    ]));

    await _createWidget(tester);
    await tester.pump(Duration(seconds: 5));

    expect(find.textContaining('Welcome user'), findsOneWidget);
  });

 tearDown(() {
    welcomeBloc?.close();
    unRegister();
  });
}

编辑添加:

对于我的其他页面,将 blocProvider 和 blocBuilder 分开很有用。这样我就可以用 MockMyBloc() 模拟我的 blocProvider,然后在 child.

中显示屏幕

我的真实小部件:

MyWidgetMakeBlocProviders(
    Widget build(context) {
        return BlocProvider<MyBloc>(
            create: (context) => MyBloc(),
            child: MyScreen(),
        );
    }
)


MyScreen(
    Widget build(context) {
        return BlocBuilder<MyBloc, MyBlocState>(
            builder: (context, state) {...}
        );
    }
)

我的测试:

testWidgets('', (tester) async {
    whenListen(MockMyBloc, Stream.fromIterable([
        InitState(),
        LoadedState()
    ]));

    await _createWidget(tester);
    await tester.pump();
    
    //expect()
});

_createWidget(tester) async {
    await tester.pumpWidget(
        MaterialApp(
            title: '',
            home: BlocProvider<MockMyBloc>(
                create: (context) => MockMyBloc(),
                child: MyScreen(),
            )
        )
    );

    await tester.pump();
}