假设,我使用来测试Flutter中的屏幕WidgetTester。有一个按钮,可通过进行导航Navigator。我想测试该按钮的行为。
WidgetTester
Navigator
小部件/屏幕
class MyScreen extends StatefulWidget { MyScreen({Key key}) : super(key: key); @override _MyScreenState createState() => _MyScreenScreenState(); } class _MyScreenState extends State<MyScreen> { @override Widget build(BuildContext context) { return Scaffold( body: Center( child: RaisedButton( onPressed: () { Navigator.of(context).pushNamed("/nextscreen"); }, child: Text(Strings.traktTvUrl) ) ) ); } }
测试
void main() { testWidgets('Button is present and triggers navigation after tapped', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp(home: MyScreen())); expect(find.byType(RaisedButton), findsOneWidget); await tester.tap(find.byType(RaisedButton)); //how to test navigator? }); }
我有一个正确的方法如何检查Navigator是否被调用?还是有一种方法可以模拟和替换导航器?
请注意,上面的代码实际上会因一个异常而失败,因为'/nextscreen'在应用程序中没有声明命名的路由。解决起来很简单,您无需指出。
'/nextscreen'
我主要关心的是如何在Flutter中正确处理此测试方案。
在flutter仓库中的导航器测试中,他们使用NavigatorObserver类观察导航:
class TestObserver extends NavigatorObserver { OnObservation onPushed; OnObservation onPopped; OnObservation onRemoved; OnObservation onReplaced; @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); } }
看起来它应该可以满足您的要求,但是它只能在顶层(MaterialApp)上运行,我不确定是否可以仅将其提供给小部件。