我有一个非常简单的任务:在Flutter中测试Navigator交互。 我调查了this answer,但找不到所选择的解决方案。
这是我到目前为止所做的:
1)假设我们的代码中有以下地方:
onTap: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => const ScreenTwo(),
),
);
},
1)然后我创建了test_observer.dart
typedef OnObservation = void Function(
Route<dynamic> route, Route<dynamic> previousRoute);
class TestObserver extends NavigatorObserver {
OnObservation onPushed;
OnObservation onPopped;
OnObservation onRemoved;
OnObservation onReplaced;
bool wasPushed = false;
bool wasPopped = false;
void expectNamedRoute(String routeName) {
onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) {
expect(route is PageRoute && route.settings.name == routeName, true);
wasPushed = true;
};
}
void expectNamedRoutePopped(String routeName) {
onPopped = (Route<dynamic> route, Route<dynamic> previousRoute) {
expect(route is ModalRoute && route.settings.name == routeName, true);
wasPopped = true;
};
}
void expectRoutePushed() {
onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) {
expect(route is ModalRoute, true, reason: 'route is not of type ModalRoute');
wasPushed = true;
};
}
@override
void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
if (onPushed != null) {
onPushed(route, previousRoute);
}
}
@override
void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
if (onPopped != null) {
onPopped(route, previousRoute);
}
}
@override
void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) {
if (onRemoved != null) {
onRemoved(route, previousRoute);
}
}
@override
void didReplace({Route<dynamic> oldRoute, Route<dynamic> newRoute}) {
if (onReplaced != null) {
onReplaced(newRoute, oldRoute);
}
}
}
2)然后创建一个包装器test_app.dart
class TestApp extends StatelessWidget {
final TestObserver navObserver = TestObserver();
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
final Widget child;
TestApp({this.child});
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: navigatorKey,
navigatorObservers: navObservers ?? [],
home: child,
routes: routes,
);
}
}
4)因此,现在在测试中,我的使用方式是:
group('with navigation', () {
TestApp widget;
setUp(() {
widget = TestApp(child: ScreenOne());
});
testWidgets('navigates to wallet balance screen',
(WidgetTester tester) async {
await tester.pumpWidget(widget);
widget.navObserver.expectRoutePushed(); // this overrides onPushed and sets up assertions in TestObserver
await tester.tap(find.byType(GestureResponder));
expect(widget.navObserver.wasPushed, true);
});
});
这确实有效
wasPushed
是否已更改。expect
语句的事实使我闻起来有点
进入TestObserver,不得不使用
widget.navObserver.expectRoutePushed();
之前的await
tester.tap(find.byType(Paper));