Flutter集成测试中使用Http_mock_adapter无响应问题求助
问题原因
测试中配置的带Mock Adapter的Dio实例被应用main函数里的Get.lazyPut(() => AppSession(Dio()))覆盖了。当你调用await tester.pumpWidget(const MyApp())时,应用的main函数会重新执行,其中的Get依赖注入逻辑会注册一个新的AppSession(带默认Dio实例),替换掉你在setUp中提前配置的测试用实例,导致登录请求使用的是真实Dio而非Mock的,因此点击按钮后无预期响应。
解决方案
方案一:抽离依赖注入逻辑(推荐)
重构应用的初始化代码,将依赖注入从main函数中分离,允许测试环境自定义初始化逻辑:
1. 修改main.dart
AppSession get currentSession => Get.find<AppSession>(); // 允许传入自定义初始化函数,默认使用生产环境配置 void main({Future<void> Function()? initDependencies}) async { await (initDependencies ?? defaultInitDependencies)(); runApp(const MyApp()); } // 生产环境默认依赖初始化 Future<void> defaultInitDependencies() async { Get.lazyPut(() => AppSession(Dio())); }
2. 修改测试代码
IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('端到端测试', () { testWidgets('邮箱密码登录测试', (tester) async { final dio = Dio(); // 配置带Mock Adapter的Dio final adjustedDio = setAdapter(dio); // 调用main时传入测试专用的依赖初始化逻辑 await main(initDependencies: () { Get.lazyPut(() => AppSession(adjustedDio)); }); // 等待页面完全加载 await tester.pumpAndSettle(); // 执行登录操作 final loginButton = find.text("LOGIN"); await tester.tap(loginButton); // 等待异步请求和页面状态更新完成 await tester.pumpAndSettle(); // 后续断言逻辑... }); });
方案二:在测试中替换已注入的实例
如果不想修改应用主代码,可以在pumpWidget后手动替换AppSession实例:
IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('端到端测试', () { testWidgets('邮箱密码登录测试', (tester) async { final dio = Dio(); final adjustedDio = setAdapter(dio); // 加载应用 await tester.pumpWidget(const MyApp()); // 替换已存在的AppSession实例(永久生效,避免被覆盖) Get.put<AppSession>(AppSession(adjustedDio), permanent: true); await tester.pumpAndSettle(); // 执行登录操作 final loginButton = find.text("LOGIN"); await tester.tap(loginButton); await tester.pumpAndSettle(); // 后续断言逻辑... }); });
额外注意事项
- 确保
setAdapter方法正确配置了Mock Adapter,匹配登录请求的HTTP方法、路径、请求参数,比如登录是POST请求时,要对应设置POST的Mock响应。 - 每次交互(点击、输入)后务必调用
await tester.pumpAndSettle(),等待异步操作(网络请求、页面渲染)完成后再执行断言,避免测试因时机问题失败。 - 测试前调用
Get.reset()可以清空之前的依赖注入状态,避免测试间的互相干扰。
内容的提问来源于stack exchange,提问作者Vetrivelu Murugesan
相关产品推荐
相关产品推荐

