如何使用未解决的 Future 对 FutureBuilder 进行小部件测试
How to widget-test FutureBuilder with unresolved Future
我想知道在 flutter widget 测试中 future 尚未完成时如何测试案例。
只要未来未解决,小部件就应该显示微调器。
我试过这个测试用例:
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。
尝试
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。
我找到了一个使用 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);
},
);
尝试使用完成器让 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);
},
);
我想知道在 flutter widget 测试中 future 尚未完成时如何测试案例。
只要未来未解决,小部件就应该显示微调器。
我试过这个测试用例:
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。
尝试
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。
我找到了一个使用 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);
},
);
尝试使用完成器让 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);
},
);