简体   繁体   English

如何使用未解决的 Future 对 FutureBuilder 进行小部件测试

[英]How to widget-test FutureBuilder with unresolved Future

I wonder how I can test the case when a future is not yet completed in flutter widget tests.我想知道如何在 flutter 小部件测试中尚未完成未来的情况下测试案例。

The widget should show a spinner as long as the future is unresolved.只要未来未解决,小部件就应该显示一个微调器。

I tride this test case:我试过这个测试用例:

testWidgets(
  'should show a spinner when loading',
  (WidgetTester tester) async {
    when(valueRepository.getValues())
        .thenAnswer((_) => Future.delayed(Duration(seconds: 30), () => []));
    await tester.pumpWidget(withApp(ValueListPage(
      valueRepository: valueRepository,
    )));

    await tester.pumpAndSettle(
        Duration(seconds: 10), EnginePhase.build, Duration(minutes: 1));

    expect(find.byType(CircularProgressIndicator), findsOneWidget);
  },
);

Result: The future is resolved and the expectation fails.结果:未来解决,期望落空。

Note: withApp initializes an App with localization.注意:withApp 初始化一个带有本地化的应用程序。 Because of that I have to call tester.pumpAndSettle() to wait for l10n.因此,我必须调用tester.pumpAndSettle()来等待 l10n。

I found a working solution with fakeAsync:我找到了一个带有 fakeAsync 的工作解决方案:

testWidgets(
  'should show a spinner when loading',
  (WidgetTester tester) async {
      when(valueRepository.getValues()).thenAnswer(
          (_) => Future.delayed(Duration(seconds: 1), () => []));
      await tester.pumpWidget(withApp(ValueListPage(
        valueRepository: valueRepository,
      )));

      await tester.pump();

      expect(find.byType(CircularProgressIndicator), findsOneWidget);
      await tester.pumpAndSettle();
      expect(find.byType(CircularProgressIndicator), findsNothing);
  },
);

Try尝试

testWidgets(
  'should show a spinner when loading',
  (WidgetTester tester) async {
    tester.runAsync(() async {
      when(valueRepository.getValues())
          .thenAnswer((_) => Future.delayed(Duration(seconds: 30), () => []));
      await tester.pumpWidget(withApp(ValueListPage(
        valueRepository: valueRepository,
      )));

      await tester.pumpAndSettle(
          Duration(seconds: 10), EnginePhase.build, Duration(minutes: 1));

      expect(find.byType(CircularProgressIndicator), findsOneWidget);
    });
  },
);

Tests run with fakeAsync by default and some async code doesn't run properly with fakeAsync.默认情况下,测试使用 fakeAsync 运行,并且某些异步代码无法使用 fakeAsync 正常运行。

Try to use completer to stay the AsyncSnapshot on waiting.尝试使用完成程序让 AsyncSnapshot 保持等待。 for example:例如:

testWidgets('should show a spinner when loading',(WidgetTester tester) async {

    Completer completer = Completer();
    when(valueRepository.getValues())
       .thenAnswer((_) => completer.future);
    await tester.pumpWidget(withApp(ValueListPage(
    valueRepository: valueRepository,
    )));

    expect(find.byType(CircularProgressIndicator), findsOneWidget); 
 },
);

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

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