Open6

Flutterでgo_routerのテスト

ak2ieak2ie

Flutterでgo_routerを使って画面遷移したときに、パスや名前が正しいかをテストする方法

ak2ieak2ie

routerの定義として次のような形があるとする

  • path: /
    • name: home
  • path: /sample
    • name: sample
final goRouter = GoRouter(
  initialLocation: '/',
  routes: [
    GoRoute(
      path: '/',
      name: 'home',
      pageBuilder: (context, state) => MaterialPage(
        child: const Home(),
        key: state.pageKey,
      ),
    ),
    GoRoute(
        path: '/sample',
        name: 'sample',
        pageBuilder: (context, state) {
          return MaterialPage(
            child: const SampleScreen(),
            key: state.pageKey,
          );
        }),
  ],
);
ak2ieak2ie

各画面では、ボタンをタップするともう一方の画面に遷移する

class Home extends ConsumerWidget {
  const Home({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Scaffold(
      body: SafeArea(
          child: Column(children: [
            ElevatedButton(
              onPressed: () {
                context.go('/sample');
              },
              child: const Text('Go to Sample'),
            ),
          ])
       )
    );
  }
}
ak2ieak2ie

テストでは、MaterialApp.routerで画面を生成してテストコードを書く

void main() {
  testWidgets('Home',
      (WidgetTester tester) async {
    await tester.pumpWidget(ProviderScope(
      child: MaterialApp.router(
        routerConfig: goRouter,
      ),
    ));
    await tester.pumpAndSettle();

    final buttonFinder = find.byType(ElevatedButton);
    expect(buttonFinder, findsOneWidget);

    // ボタンをタップ
    await tester.tap(buttonFinder);
    await tester.pumpAndSettle();

    // タップ後の遷移先パスをテスト
    expect(GoRouterState.of(tester.element(buttonFinder)).uri.path, '/sample');\
    // nameをテストするなら次のように書く
    expect(GoRouterState.of(tester.element(buttonFinder)).name., 'sample');
  });
}
ak2ieak2ie

初期画面のテストは上のように書けるけど、それ以外は画面に遷移させてからテストするようにする

// tester.pumpWidget...

// 任意の画面に遷移する
GoRouter.of(tester.element(find.byType(ElevatedButton))).go('/sample');
await tester.pumpAndSettle();

// expect...