Hil*_*tor 6 testing flutter bloc
我有一个EmailScreen(有状态的小部件),它有一个文本输入和一个按钮。仅当输入有效的电子邮件时该按钮才会启用。
我正在使用 Bloc,我的屏幕上有InitialEmailState和ValidEmailInputState,并且当我运行该应用程序时它工作正常。
在我的小部件测试中,在 bloc 有机会更新状态之前,第二个期望失败了:
\n\n\n testWidgets(\'when valid email is input, button is enabled\', (tester) async {\n const validEmail = \'email@provider.com\';\n\n emailBloc.listen((event) {\n print(\'NEW EVENT: \' + event.toString());\n });\n\n await bootUpWidget(tester, emailScreen);\n\n final BottomButton button = tester.widget(\n find.widgetWithText(BottomButton, \'CONTINUE\'));\n\n expect(button.enabled, isFalse);\n\n await tester.enterText(find.byType(TextInputScreen), validEmail);\n await tester.pumpAndSettle();\n\n expect(button.enabled, isTrue);\n });\nRun Code Online (Sandbox Code Playgroud)\n\n这是我得到的输出:
\n\nNEW EVENT: InitialEmailState\n\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1 EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK \xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nThe following TestFailure object was thrown running a test:\n Expected: true\n Actual: <false>\n\n...\n\nThe test description was:\n when valid email is input, button is enabled\n\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nTest failed. See exception logs above.\nThe test description was: when valid email is input, button is enabled\n\nNEW EVENT: InputValidEmailState\n\xe2\x9c\x96 when valid email is input, button is enabled\nExited (1)\nRun Code Online (Sandbox Code Playgroud)\n\n正如您所看到的,它打印初始状态,失败第二个期望,然后打印期望状态。
\n\n提前致谢 :)
\n\n==更新==
\n\nLiveTestWidgetsFlutterBinding();我们设法通过添加到 main 的开头来使其工作。但这感觉不是一个好的解决方案。
小智 5
在 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()`
}
Run Code Online (Sandbox Code Playgroud)
我在 BLoC 中放置了断点来找出问题所在,事实证明,在不使用 的情况下,在 BLoC 流发出新状态之前正在评估expectLater法线。expect也就是说 BLoC 确实发出了一个新的状态,但此时测试用例已经运行到最后。
通过使用expectLater,它会在新状态发出后进行评估。
| 归档时间: |
|
| 查看次数: |
3100 次 |
| 最近记录: |