Search code examples
flutterdartroutesflutter-go-router

No GoRouter found in context in widget tests


I'm trying to mock go_router in my widget tests but keep getting this error:

══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
The following assertion was thrown while handling a gesture:
No GoRouter found in context
'package:go_router/src/router.dart':
Failed assertion: line 300 pos 12: 'inherited != null'

When the exception was thrown, this was the stack:
#2      GoRouter.of (package:go_router/src/router.dart:300:12)
#3      GoRouterHelper.pushNamed (package:go_router/src/misc/extensions.dart:50:16)
#4      _ProfileEditWidgetState._getSubmitButton.<anonymous closure>.<anonymous closure> (package:app/widgets/profile/profile_edit_widget.dart:236:33)

I'm using go_router 6.0.0

Here's what I have in my test:

final router = MockGoRouter();
when(router.pushNamed(any)).thenReturn(null);

await tester.pumpWidget(
      MultiProvider(
        providers: [
          BlocProvider<ProfileBloc>(create: (context) => profileBloc),
        ],
        child: MaterialApp(
          locale: const Locale("en"),
          home: InheritedGoRouter(
            goRouter: router,
            child: ProfileEditWidget(),
          ),
        ),
      ),
    );

await tester.pump();
await tester.tap(find.byKey(const Key('btnSubmit')));
await tester.pump();

In my profile edit widget in the submit button on pressed this is what I have:

context.pushNamed(
    VERIFY_PHONE,
     queryParams: {
         'updatedPhone': phone
      },
)

There also seems to be no documentation on go to handle testing with go router


Solution

  • Try to change the MaterialApp to MaterialApp.router

    And use GoRouter() instead of MockGoRouter()

    import 'package:go_router/go_router.dart';
    
    // GoRouter configuration
    final _router = GoRouter(
      routes: [
        GoRoute(
          path: '/',
          builder: (context, state) => HomeScreen(),
        ),
      ],
    );
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp.router(
          routerConfig: _router,
        );
      }
    }