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

使用Mocktail测试Flutter ApiProvider报Null不是Future<Response>子类型错误

问题根因

  • HTTP请求Mock不完整:你在测试中对httpClient.post的Mock只匹配了第一个位置参数Uri,但是业务代码中调用post方法时还传入了body命名参数,Mocktail无法匹配到符合完整参数的Stub,因此返回Null,触发Null不是Future<Response>类型错误。
  • 异常测试写法错误:你直接await调用会抛出异常的login方法,还没执行到expect断言就会触发运行时错误,不符合异步异常测试的写法要求。
  • 多余的被测类Mock:你后续添加的对apiProvider.login本身的Mock完全错误,单元测试中被测类的逻辑需要真实执行,只需要Mock它的外部依赖(也就是httpClient),对被测类自身方法Mock会导致真实逻辑无法运行,同时返回的String类型和post方法需要的Response类型不匹配,触发第二个类型错误。

修复方案

修改测试代码中login分组的测试逻辑,补全Mock的参数匹配,调整异常测试写法,删除多余的被测类Mock即可:

group('login', () {
  test('Throws Exception on non-200 response', () async {
    final response = MockResponse();

    when(() => response.statusCode).thenReturn(400);
    when(() => response.body).thenReturn('');
    // 补全post方法的参数匹配,包含body命名参数
    when(() => httpClient.post(any(), body: any(named: 'body')))
        .thenAnswer((_) async => response);

    // 不要提前await,使用expectLater配合异步异常匹配
    await expectLater(apiProvider.login(const User.empty()), throwsA(isA<Exception>()));
  });
});

如果需要更严格的参数校验,也可以将any(named: 'body')替换为实际传入的参数{"username": "", "password": ""},实现对请求参数的精准验证。

内容的提问来源于stack exchange,提问作者Brenno Barbosa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 11:45:03