如何创建使用go_router StatefulNavigationShell的Widget测试并解决路由Mock问题
1. 准备Mock工具
使用Mockito生成StatefulNavigationShell的Mock类,先确保dev_dependencies包含依赖:
dev_dependencies: flutter_test: sdk: flutter mockito: ^5.4.0 build_runner: ^2.4.4
创建mock文件(如test/mocks/mock_go_router.dart):
import 'package:go_router/go_router.dart'; import 'package:mockito/mockito.dart'; class MockStatefulNavigationShell extends Mock implements StatefulNavigationShell {}
运行命令生成mock代码:
flutter pub run build_runner build
2. 测试组件基本渲染
验证MainScreen正确布局,且CustomNavBar接收了正确的navigationShell实例:
import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:your_app/main_screen.dart'; import 'package:your_app/custom_nav_bar.dart'; import 'mocks/mock_go_router.dart'; void main() { testWidgets('MainScreen renders layout and passes shell to CustomNavBar', (tester) async { final mockShell = MockStatefulNavigationShell(); when(mockShell.build(any)).thenReturn(const SizedBox(key: Key('shell-content'))); await tester.pumpWidget( MaterialApp( home: MainScreen(navigationShell: mockShell), ), ); // 验证核心布局元素存在 expect(find.byType(Scaffold), findsOneWidget); expect(find.byKey(const Key('shell-content')), findsOneWidget); expect(find.byType(CustomNavBar), findsOneWidget); // 验证CustomNavBar拿到了正确的mock实例 final navBar = tester.widget<CustomNavBar>(find.byType(CustomNavBar)); expect(navBar.navigationShell, equals(mockShell)); }); }
3. 测试底部导航切换逻辑
验证点击CustomNavBar按钮时,会正确调用StatefulNavigationShell.goBranch方法:
testWidgets('CustomNavBar triggers goBranch on shell when tapped', (tester) async { final mockShell = MockStatefulNavigationShell(); when(mockShell.build(any)).thenReturn(const SizedBox()); await tester.pumpWidget( MaterialApp( home: MainScreen(navigationShell: mockShell), ), ); // 点击底部导航第一个按钮(根据你的组件实际Key调整) await tester.tap(find.byKey(const Key('nav-item-0'))); await tester.pumpAndSettle(); // 验证goBranch方法被正确调用 verify(mockShell.goBranch(0, initialLocation: anyNamed('initialLocation'))).called(1); });
4. 额外注意事项
- 若
CustomNavBar依赖StatefulNavigationShell的currentIndex等属性,测试前需通过when(mockShell.currentIndex).thenReturn(0)模拟返回值。 - 若要测试真实页面切换效果,可结合GoRouter的测试路由配置编写集成测试,而非仅做Widget层面的Mock验证。
内容的提问来源于stack exchange,提问作者Arnoodles
相关产品推荐
相关产品推荐

