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

Dart单元测试:如何Mock内部API函数以测试目标函数

Dart异步函数单元测试:Mock内部API调用

要实现不调用真实API的单元测试,核心是让API依赖可替换,下面提供两种实用方案:

方案一:函数参数注入(轻量级,无需额外库)

先改造原函数,把API调用作为可选参数传入,这样测试时可以替换成模拟实现:

改造待测试函数

import 'package:test/test.dart';

// 真实API函数
Future<int> API() async {
  // 真实的API请求逻辑
  return 0;
}

// 修改function,允许传入自定义的api函数
Future<int> function({Future<int> Function() api = API}) async {
  final int value = await api();
  return value + 1;
}

编写单元测试

测试时直接传入模拟的API函数,指定返回值:

void main() {
  test('当API返回1时,function应返回2', () {
    // 模拟API返回1
    final mockApi = () async => 1;
    expect(function(api: mockApi), completion(equals(2)));
  });

  test('当API返回5时,function应返回6', () {
    final mockApi = () async => 5;
    expect(function(api: mockApi), completion(equals(6)));
  });
}

方案二:用Mockito Mock类(适合复杂场景)

如果API逻辑复杂,建议将其封装成类,再用Mockito库来创建Mock对象,还能验证API方法的调用情况。

步骤1:封装API为类

class ApiService {
  Future<int> fetchValue() async {
    // 真实API请求逻辑
    return 0;
  }
}

// 修改function,依赖ApiService类
Future<int> function(ApiService apiService) async {
  final int value = await apiService.fetchValue();
  return value + 1;
}

步骤2:添加依赖

在pubspec.yaml的dev_dependencies中添加:

dev_dependencies:
  test: any
  mockito: ^5.4.0
  build_runner: ^2.4.4

步骤3:生成Mock类

创建mock_api_service.dart文件:

import 'package:mockito/mockito.dart';
import 'path/to/api_service.dart';

class MockApiService extends Mock implements ApiService {}

运行命令生成Mock代码:

dart run build_runner build

步骤4:编写测试

import 'package:test/test.dart';
import 'package:mockito/mockito.dart';
import 'mock_api_service.dart';
import 'path/to/function.dart';

void main() {
  late MockApiService mockApiService;

  // 每个测试前初始化Mock对象
  setUp(() {
    mockApiService = MockApiService();
  });

  test('API返回1时,function返回2', () async {
    // 设定Mock方法的返回值
    when(mockApiService.fetchValue()).thenAnswer((_) async => 1);
    
    // 调用待测试函数
    final result = await function(mockApiService);
    
    // 验证结果正确
    expect(result, equals(2));
    // 验证API方法被调用了一次
    verify(mockApiService.fetchValue()).called(1);
  });
}

关键说明

原代码的问题在于直接硬编码调用API(),没有预留替换入口,所以必须先改造代码让依赖可注入,这是实现可测试性的核心。

内容的提问来源于stack exchange,提问作者Yukinosuke Takada

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 13:35:34