You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 19:50:16