How to widget-test FutureBuilder with unresolved Future

Issue

I wonder how I can test the case when a future is not yet completed in flutter widget tests.

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. Because of that I have to call tester.pumpAndSettle() to wait for l10n.

Solution

I found a working solution with 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);
  },
);

Answered By – svi3c

Answer Checked By – Dawn Plyler (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *