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

Flutter单元测试报错:type 'Null' is not a subtype of type 'Future<Response>'

解决Mockito模拟API响应时的Null类型错误

常见原因及修复步骤

1. 未正确设置Mock方法的返回值

Mockito的when()方法未指定thenReturn()或thenAnswer()时,会默认返回null,空安全下这会触发类型不匹配错误。

错误示例:

when(mockApiClient.fetchData()).thenAnswer((_) => null); // 返回null,不符合Future<Response>类型

修复方式:
返回合法的Future<Response>实例,哪怕是模拟的空响应:

import 'package:http/http.dart' as http;

// 模拟成功响应
when(mockApiClient.fetchData()).thenAnswer((_) async => http.Response('{"data": []}', 200));

// 模拟错误响应
when(mockApiClient.fetchData()).thenAnswer((_) async => http.Response('Error', 404));

2. Mock类未完整实现抽象方法

若API客户端是抽象类,Mockito生成的Mock类可能遗漏部分方法实现,导致调用时返回null。

修复方式:
确保用@GenerateMocks([YourApiClient])正确生成Mock类,且所有被调用的方法都通过when()设置了返回值。

3. 空安全下的类型声明问题

检查API客户端方法的返回值是否明确为Future<Response>而非Future<Response?>。如果是前者,必须返回非空的Future<Response>;如果是后者,Mock返回null是允许的,但测试逻辑需做对应处理。

示例检查:

// 正确的非空声明
Future<http.Response> fetchData();

// 可空声明,Mock可返回null,但需处理
Future<http.Response?> fetchData();

4. 方法调用签名不匹配

Mockito的when()会严格匹配方法参数,若测试中调用的参数和Mock时设置的参数不一致,会返回null。

错误示例:

// Mock时指定参数为1
when(mockApiClient.fetchItem(1)).thenAnswer((_) async => http.Response('{}', 200));

// 测试中调用参数为2
await mockApiClient.fetchItem(2); // 返回null,触发错误

修复方式:
保证参数完全匹配,或用any匹配任意参数:

import 'package:mockito/mockito.dart';

when(mockApiClient.fetchItem(any)).thenAnswer((_) async => http.Response('{}', 200));

完整测试代码示例

import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart' as http;
import 'package:mockito/mockito.dart';

// 抽象API客户端
abstract class ApiClient {
  Future<http.Response> fetchData();
}

// 生成Mock类
class MockApiClient extends Mock implements ApiClient {}

void main() {
  late MockApiClient mockApiClient;

  setUp(() {
    mockApiClient = MockApiClient();
  });

  test('fetchData returns successful response', () async {
    // 设置Mock返回值
    when(mockApiClient.fetchData()).thenAnswer((_) async => http.Response('{"data": "test"}', 200));

    // 调用方法
    final response = await mockApiClient.fetchData();

    // 断言结果
    expect(response.statusCode, 200);
    expect(response.body, '{"data": "test"}');
  });
}

内容的提问来源于stack exchange,提问作者Gabriel Abuka

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 18:32:45