Как проверить виджет FutureBuilder с нерешенным Future
Интересно, как я могу проверить случай, когда будущее еще не завершено в тестах виджетов флаттера?
Виджет должен показывать счетчик, пока будущее не разрешено.
Я tride этот тестовый пример:
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);
},
);
Результат: будущее решено, и ожидание не удается.
Примечание: withApp инициализирует приложение с локализацией. Из-за этого я должен позвонить tester.pumpAndSettle()
ждать l10n.
2 ответа
Решение
Я нашел рабочее решение с помощью 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);
},
);
Пытаться
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);
});
},
);
Тесты запускаются с fakeAsync по умолчанию, а некоторые асинхронные коды не работают должным образом с fakeAsync.
Попытайтесь использовать завершитель, чтобы сохранить AsyncSnapshot при ожидании. например:
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);
},
);