How to mock navigation arguments for testing flutter screen widgets? How to mock navigation arguments for testing flutter screen widgets? flutter flutter

How to mock navigation arguments for testing flutter screen widgets?


The way that I've found is the same approach how flutter guys are testing it:https://github.com/flutter/flutter/blob/d03aecab58f5f8b57a8cae4cf2fecba931f60673/packages/flutter/test/widgets/navigator_test.dart#L715

Basically they create a MaterialApp, put a button that after pressing will navigate to the tested page.

My modified solution:

Future<void> pumpArgumentWidget(  WidgetTester tester, {  @required Object args,  @required Widget child,}) async {  final key = GlobalKey<NavigatorState>();  await tester.pumpWidget(    MaterialApp(      navigatorKey: key,      home: FlatButton(        onPressed: () => key.currentState.push(          MaterialPageRoute<void>(            settings: RouteSettings(arguments: args),            builder: (_) => child,          ),        ),        child: const SizedBox(),      ),    ),  );  await tester.tap(find.byType(FlatButton));  await tester.pumpAndSettle(); // Might need to be removed when testing infinite animations}

This approach works ok-ish, had some issues with testing progress indicators as it was not able to find those even when debugDumpApp displayed them.


If you are using a Dependency Injector such as I am, you may need to avoid pass contextual arguments to the constructor if your view is not built at the time the view class is instantiated. Otherwise, just use the view constructor as someone suggested.

So if you can't use constructor as I can't, you can solve this using Navigator directly in your tests. Navigator is a widget, so just use it to return your screen. Btw, it has no problem with Progress Indicator as pointed above.

import 'package:commons/core.dart';import 'package:flutter/material.dart';import 'package:flutter_test/flutter_test.dart';import 'package:mockito/mockito.dart';class MyCustomArgumentsMock extends Mock implements MyCustomArguments {}void main() {  testWidgets('indicator is shown when screen is opened', (tester) async {    final MyCustomArguments mock = MyCustomArgumentsMock();    await tester.pumpWidget(MaterialApp(      home: Navigator(        onGenerateRoute: (_) {          return MaterialPageRoute<Widget>(            builder: (_) => TestScreen(),            settings: RouteSettings(arguments: mock),          );        },      ),    ));    expect(find.byType(CircularProgressIndicator), findsOneWidget);  });}