簡體   English   中英

如何讓小部件測試等到 Bloc 更新狀態?

[英]How to make widget test wait until Bloc has updated the state?

我有一個具有文本輸入和按鈕的EmailScreen (有狀態小部件)。 該按鈕僅在輸入有效電子郵件時啟用。

我使用的陣營,和我的屏幕有InitialEmailStateValidEmailInputState ,當我運行的應用程序,它工作正常。

在我的小部件測試中,第二個期望在 bloc 有機會更新狀態之前失敗:


  testWidgets('when valid email is input, button is enabled', (tester) async {
    const validEmail = 'email@provider.com';

    emailBloc.listen((event) {
      print('NEW EVENT: ' + event.toString());
    });

    await bootUpWidget(tester, emailScreen);

    final BottomButton button = tester.widget(
        find.widgetWithText(BottomButton, 'CONTINUE'));

    expect(button.enabled, isFalse);

    await tester.enterText(find.byType(TextInputScreen), validEmail);
    await tester.pumpAndSettle();

    expect(button.enabled, isTrue);
  });

這是我得到的輸出:

NEW EVENT: InitialEmailState
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure object was thrown running a test:
  Expected: true
  Actual: <false>

...

The test description was:
  when valid email is input, button is enabled
════════════════════════════════════════════════════════════════════════════════════════════════════
Test failed. See exception logs above.
The test description was: when valid email is input, button is enabled

NEW EVENT: InputValidEmailState
✖ when valid email is input, button is enabled
Exited (1)

如您所見,它打印初始狀態,第二個期望失敗,然后打印期望狀態。

提前致謝 :)

== 更新 ==

我們設法通過添加LiveTestWidgetsFlutterBinding();來使其工作LiveTestWidgetsFlutterBinding(); 到我們主要的開始。 但感覺這不是一個好的解決方案。

在 BLoC 驅動的 UI 小部件中遇到了同樣的問題,我發現解決方案非常簡單:使用expectLater()而不是expect()來等待 BLoC 狀態更新:

testWidgets('test widgets driven by BLoC', (tester) async {
  await tester.pumpWidget(yourWidget);

  await tester.tap(loginButton); // Do something like tapping a button, entering text
  await tester.pumpAndSettle();

  await expectLater(findSomething, findsOneWidget); // IMPRTANT: use `expectLater` to wait for BLoC state update
  expect(findSomethingElse, findsOneWidget); // Subsequently you can use normal version `expect` until next `tester.pumpAndSettle()`
}

我將斷點放入 BLoC 以找出問題所在,結果證明在不使用expectLater ,在 BLoC 流發出新狀態之前會評估正常的expect 也就是說BLoC確實發出了一個新的狀態,但是那個時候測試用例已經運行到最后了。

通過使用expectLater ,它會在新狀態發出后進行評估。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM