How to Test Navigation Via Navigator In Flutter ??
Earlier we have been through various articles based on how to change from Stateless Widget to Stateful Widget. So, in this article, we will go through How to Test Navigation Via Navigator In Flutter.
Take a deep dive into Learning Flutter with Flutter Agency.
How to Test Navigation Via Navigator In Flutter??
In the navigator tests in the flutter repo they use the NavigatorObserver class to observe navigations:
igations: 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); } }
Navigation could be abstracted away from a screen or a widget. The test can mock and inject this abstraction. This approach should be sufficient for testing such behavior.
There are several ways how to achieve that. I will show one of those, for purpose of this response. Perhaps it’s possible to simplify it a bit or to make it more “Darty”.
Abstraction for navigation 👇
class AppNavigatorFactory { AppNavigator get(BuildContext context) => AppNavigator._forNavigator(Navigator.of(context)); } class TestAppNavigatorFactory extends AppNavigatorFactory { final AppNavigator mockAppNavigator; TestAppNavigatorFactory(this.mockAppNavigator); @override AppNavigator get(BuildContext context) => mockAppNavigator; } class AppNavigator { NavigatorState _flutterNavigator; AppNavigator._forNavigator(this._flutterNavigator); void showNextscreen() { _flutterNavigator.pushNamed('/nextscreen'); } }
Injection into a widget 👇
class MyScreen extends StatefulWidget { final _appNavigatorFactory; MyScreen(this._appNavigatorFactory, {Key key}) : super(key: key); @override _MyScreenState createState() => _MyScreenState(_appNavigatorFactory); } class _MyScreenState extends State<MyScreen> { final _appNavigatorFactory; _MyScreenState(this._appNavigatorFactory); @override Widget build(BuildContext context) { return Scaffold( body: Center( child: RaisedButton( onPressed: () { _appNavigatorFactory.get(context).showNextscreen(); }, child: Text(Strings.traktTvUrl) ) ) ); } }
Example of a test (Uses Mockito for Dart) 👇
class MockAppNavigator extends Mock implements AppNavigator {} void main() { final appNavigator = MockAppNavigator(); setUp(() { reset(appNavigator); }); testWidgets('Button is present and triggers navigation after tapped', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp(home: MyScreen(TestAppNavigatorFactory()))); expect(find.byType(RaisedButton), findsOneWidget); await tester.tap(find.byType(RaisedButton)); verify(appNavigator.showNextscreen()); }); }
So you can create a mocked NavigatorObserver to avoid any extra boilerplate:
import 'package:mockito/mockito.dart'; class MockNavigatorObserver extends Mock implements NavigatorObserver {}
So that would translate to your test case as shown in the below snippet:
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(any, any)); /// You'd also want to be sure that your page is now /// present in the screen. expect(find.byType(DetailsPage), findsOneWidget); }); }
You can find a detailed article on it from which you can find it here.
Conclusion:
So in this article, we have been through How to Test Navigation Via Navigator In Flutter.
If you need articles or videos on any specific topic, Do let us know.
Keep Learning !!! Keep Fluttering !!!
Do let us know in the comments if you are still confused in flutter!! we would love to help you 🙂
FlutterAgency.com is our portal Platform dedicated to Flutter Technology and Flutter Developers. The portal is full of cool resources from Flutter like Flutter Widget Guide, Flutter Projects, Code libs and etc.
FlutterAgency.com is one of the most popular online portals dedicated to Flutter Technology and daily thousands of unique visitors come to this portal to enhance their knowledge of Flutter.
Contemporary ventures
Recent blog
ready to get started?
Fill out the form below and we will be in touch soon!
"*" indicates required fields