如何在Flutter中通过Navigator测试导航 [英] How to test navigation via Navigator in Flutter

查看:96
本文介绍了如何在Flutter中通过Navigator测试导航的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Let's say, I have a test for a screen in Flutter using WidgetTester. There is a button, which executes a navigation via Navigator. I would like to test behavior of that button.

小部件/屏幕

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是否被调用?还是有一种方法可以模拟并替换导航器?

I there a proper way how to check, that Navigator was called? Or is there a way to mock and replace navigator?

请注意,上面的代码实际上会失败,但有一个例外,因为没有命名路由'/ nextscreen'在应用程序中声明。这很容易解决,不需要指出。

Pleas note, that code above will actually fail with an exception, because there is no named route '/nextscreen' declared in application. That's simple to solve and you don't need to point it out.

我主要关心的是如何在Flutter中正确地处理此测试方案。

My main concern is how to correctly approach this test scenario in Flutter.

推荐答案

扑扑仓库中的导航器测试,它们使用 NavigatorObserver 类来观察导航:

In the navigator tests in the flutter repo they use the NavigatorObserver class to observe navigations:

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)上起作用,我不确定是否可以仅将其提供给小部件。

This looks like it should do what you want, however it may only work form the top level (MaterialApp), I'm not sure if you can provide it to just a widget.

这篇关于如何在Flutter中通过Navigator测试导航的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆