比方说,我使用 WidgetTester
对Flutter中的屏幕进行了测试 . 有一个按钮,通过 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'
. 那个's simple to solve and you don'需要指出来 .
我主要关心的是如何在Flutter中正确地处理这个测试场景 .
3 Answers
以下解决方案是,一般的方法,而不是特定于Flutter .
导航可以从屏幕或小部件中抽象出来 . 测试可以模拟并注入此抽象 . 这种方法应该足以测试这种行为 .
有几种方法可以实现这一目标 . 为了回应这个问题,我将展示其中一个 . 也许有可能简化它或使它更“Darty” .
Abstraction for navigation
Injection into a widget
Example of a test (使用Mockito for Dart)
虽然Danny所说的是正确且有效的,但你也可以创建一个模拟的NavigatorObserver来避免任何额外的样板:
这将转换为您的测试用例如下:
我在我的博客which you can find here上写了一篇深入的文章 .
在navigator tests in the flutter repo中,他们使用NavigatorObserver类来观察导航:
这看起来应该做你想要的,但是它可能只能在顶级(MaterialApp)工作,我不确定你是否可以只将它提供给一个小部件 .