问题
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.
回答1:
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.
回答2:
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);
},
);
来源:https://stackoverflow.com/questions/52472836/how-to-widget-test-futurebuilder-with-unresolved-future