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

如何使用http_mock_adapter验证已发起的Dio HTTP请求?

使用http_mock_adapter验证请求发起的解决方案

你不需要mock上层调用类,http_mock_adapter本身内置了请求记录能力,可直接用来做验证,是最优解。

方案1:使用内置history属性(优先推荐)

DioAdapter实例会自动存储所有经过它的请求记录,直接读取history属性即可断言请求是否发起、参数是否正确,示例代码如下:

import 'package:dio/dio.dart';
import 'package:http_mock_adapter/http_mock_adapter.dart';
import 'package:test/test.dart';

void main() {
  late Dio dio;
  late DioAdapter mockAdapter;

  setUp(() {
    dio = Dio();
    mockAdapter = DioAdapter(dio: dio);
    dio.httpClientAdapter = mockAdapter;

    // 预先设置模拟响应
    mockAdapter.onGet(
      '/user',
      (server) => server.reply(200, {'id': 1, 'name': 'test'}),
      queryParameters: {'id': '1'},
    );
  });

  test('验证指定GET请求成功发起', () async {
    // 执行业务代码触发请求
    await dio.get('/user', queryParameters: {'id': '1'});

    // 断言请求记录
    // 1. 验证总请求数
    expect(mockAdapter.history.length, 1);
    // 2. 验证请求方法、路径、参数
    final targetRequest = mockAdapter.history.first;
    expect(targetRequest.method, 'GET');
    expect(targetRequest.path, '/user');
    expect(targetRequest.queryParameters, {'id': '1'});
    // 也可验证请求头、请求体等其他属性
  });
}

你还可以自定义匹配规则做更灵活的验证:

  • 验证指定路径的POST请求恰好发起2次:
    final postRequests = mockAdapter.history.where(
      (req) => req.method == 'POST' && req.path == '/submit'
    );
    expect(postRequests, hasLength(2));
    
  • 验证从未发起过到/delete路径的请求:
    final deleteRequests = mockAdapter.history.where((req) => req.path == '/delete');
    expect(deleteRequests, isEmpty);
    

方案2:自定义拦截器记录请求(可选)

如果你有特殊的统计需求,也可以给Dio实例添加自定义拦截器自行记录请求:

class RequestRecordInterceptor extends Interceptor {
  List<RequestOptions> recordedRequests = [];

  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    recordedRequests.add(options);
    super.onRequest(options, handler);
  }
}

// 使用时添加到dio实例
final recordInterceptor = RequestRecordInterceptor();
dio.interceptors.add(recordInterceptor);

// 验证时直接访问recordInterceptor.recordedRequests做断言

上述两种方案都不需要额外维护上层调用类的桩代码,远优于你提到的mock上层类的方案,优先使用方案1即可。

内容的提问来源于stack exchange,提问作者Hannes Hultergård

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 04:15:03