Jos*_*cik 6 dart flutter flutter-test
比方说,我在Flutter中使用了一个屏幕测试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)
)
)
);
}
}
Run Code Online (Sandbox Code Playgroud)
测试
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?
});
}
Run Code Online (Sandbox Code Playgroud)
我有一个正确的方法如何检查,导航器被调用?或者有没有办法模拟和替换导航器?
请注意,上面的代码实际上会因异常而失败,因为'/nextscreen'在应用程序中没有声明命名的路由.这很容易解决,你不需要指出它.
我主要关心的是如何在Flutter中正确地处理这个测试场景.
Iir*_*kka 27
虽然Danny所说的是正确且有效的,但你也可以创建一个模拟的NavigatorObserver来避免任何额外的样板:
class MockNavigatorObserver extends Mock implements NavigatorObserver {}
Run Code Online (Sandbox Code Playgroud)
这将转换为您的测试用例如下:
void main() {
testWidgets('Button is present and triggers navigation after tapped',
(WidgetTester tester) async {
final mockObserver = MockNavigatorObserver();
await tester.pumpWidget(
MaterialApp(
home: MyScreen(),
navigatorObservers: [mockObserver],
),
);
expect(find.byType(RaisedButton), findsOneWidget);
await tester.tap(find.byType(RaisedButton));
await tester.pumpAndSettle();
/// Verify that a push event happened
verify(mockObserver.didPush(typed(any), typed(any)));
/// You'd also want to be sure that your page is now
/// present in the screen.
expect(find.byType(DetailsPage), findsOneWidget);
});
}
Run Code Online (Sandbox Code Playgroud)
我在博客上写了一篇关于这个的深入文章,你可以在这里找到.
在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);
}
}
Run Code Online (Sandbox Code Playgroud)
看起来它应该可以满足您的要求,但是它只能在顶层(MaterialApp)上运行,我不确定是否可以仅将其提供给小部件。
| 归档时间: |
|
| 查看次数: |
3827 次 |
| 最近记录: |