如何在单元测试中Mock Navigator.of(context).pushNamed()的返回值?
你需要用mockito库Mock Navigator的pushNamed方法,指定其返回true或false,再验证全局变量的状态变化。以下是完整实现步骤和代码示例:
1. 依赖准备
确保你的pubspec.yaml包含测试所需依赖:
dev_dependencies: flutter_test: sdk: flutter mockito: ^5.4.0
2. 示例全局变量与目标函数
假设你有如下全局状态类和需要测试的导航处理函数:
// 全局状态类 class GlobalState { static bool isGlobalUpdated = false; static void updateGlobal() { isGlobalUpdated = true; } static void reset() { isGlobalUpdated = false; } } // 需要测试的导航处理函数 Future<void> handleNavigation(BuildContext context) async { final isUpdated = await Navigator.of(context).pushNamed('/targetRoute'); if (isUpdated == true) { GlobalState.updateGlobal(); } }
3. 编写单元测试
通过testWidgets创建两个测试用例,分别Mock返回true和false的场景:
import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; // Mock NavigatorObserver,避免真实导航操作 class MockNavigatorObserver extends Mock implements NavigatorObserver {} void main() { // 每次测试前重置全局变量,保证测试独立性 setUp(() { GlobalState.reset(); }); testWidgets('pushNamed返回true时,全局变量应被更新', (tester) async { // 构建包含目标按钮的MaterialApp,注入Mock导航观察者 await tester.pumpWidget( MaterialApp( home: Scaffold( body: Builder( builder: (context) { return ElevatedButton( onPressed: () => handleNavigation(context), child: const Text('Test'), ); }, ), ), navigatorObservers: [MockNavigatorObserver()], ), ); // 获取有效BuildContext final context = tester.element(find.byType(ElevatedButton)); // Mock pushNamed方法,指定返回true when(Navigator.of(context).pushNamed('/targetRoute')).thenAnswer((_) async => true); // 执行目标函数 await handleNavigation(context); // 断言全局变量状态 expect(GlobalState.isGlobalUpdated, isTrue); }); testWidgets('pushNamed返回false时,全局变量不应被更新', (tester) async { await tester.pumpWidget( MaterialApp( home: Scaffold( body: Builder( builder: (context) { return ElevatedButton( onPressed: () => handleNavigation(context), child: const Text('Test'), ); }, ), ), navigatorObservers: [MockNavigatorObserver()], ), ); final context = tester.element(find.byType(ElevatedButton)); // Mock pushNamed方法,指定返回false when(Navigator.of(context).pushNamed('/targetRoute')).thenAnswer((_) async => false); await handleNavigation(context); // 断言全局变量状态 expect(GlobalState.isGlobalUpdated, isFalse); }); }
核心说明
- 使用
mockito的when方法直接MockNavigator.of(context).pushNamed的返回值,无需关注真实导航流程 - 每次测试前通过
setUp重置全局变量,确保单个测试用例的独立性 - 通过
testWidgets构建Widget树获取有效的BuildContext,因为Navigator必须依附于可用上下文
内容的提问来源于stack exchange,提问作者countpablo
相关产品推荐
相关产品推荐

