如何在Flutter中通过Navigator测试导航?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (274)

比方说,我在Flutter中使用了一个屏幕测试WidgetTester。有一个通过执行导航Navigator的按钮。我想测试该按钮的行为。

Widget/Screen

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)
            )
        )
    );
  }

}

Test

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?    
  });
}

如何检查导航器是否被调用?或者有没有办法模拟和替换导航器?

上面的代码实际上会因异常而失败,因为'/nextscreen'在应用程序中没有声明的命名路由。这很容易解决,不需要指出它。

我主要关注的是如何在Flutter中正确地处理这个测试场景。

提问于
用户回答回答于

在flutter repo中的导航器测试中,他们使用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)工作,我不确定你是否可以将它提供给一个小部件。

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励