如何配置undici MockAgent重复拦截同一API端点?
解决Undici MockAgent单次拦截问题,实现持续API拦截
核心问题根源
Undici 默认的 intercept 是单次生效的,调用一次后拦截规则就会被消耗,后续请求会走真实HTTP。要实现全程拦截,关键是给拦截规则加上持久化配置。
方案一:用MockAgent创建持久化拦截器
通过创建绑定目标API的MockPool,给拦截规则开启persist: true,就能让同一端点的所有请求都被拦截:
const { MockAgent, setGlobalDispatcher } = require('undici'); // 初始化MockAgent并设为全局Dispatcher,替换默认的fetch调度器 const mockAgent = new MockAgent(); setGlobalDispatcher(mockAgent); // 绑定目标API的origin,获取对应的MockPool const mockPool = mockAgent.get('https://api.example.com'); // 配置持久化拦截:persist: true 是核心 mockPool.intercept({ path: '/target-endpoint', method: 'GET' }) .reply(200, { code: 0, data: 'mocked content' }) .persist(); // 开启后,该规则对所有匹配请求生效 // 测试多次调用(包括循环内的请求) async function testLoopCalls() { // 第一次调用 const res1 = await fetch('https://api.example.com/target-endpoint'); console.log(await res1.json()); // 循环调用5次,全部被拦截 for (let i = 0; i < 5; i++) { const res = await fetch('https://api.example.com/target-endpoint'); console.log(`第${i+2}次调用结果:`, await res.json()); } } testLoopCalls();
方案二:动态响应的持久拦截
如果需要根据调用次数或参数返回不同响应,可以用函数形式的reply,配合持久化:
const { MockAgent, setGlobalDispatcher } = require('undici'); const mockAgent = new MockAgent(); setGlobalDispatcher(mockAgent); let callTimes = 0; mockAgent.get('https://api.example.com') .intercept({ path: '/dynamic-data', method: 'GET' }) .reply(() => { callTimes++; // 根据调用次数返回不同状态和内容 return callTimes <= 3 ? [200, { msg: `第${callTimes}次请求成功` }] : [429, { msg: '请求过于频繁' }]; }) .persist(); // 测试动态响应 async function testDynamicReply() { for (let i = 0; i < 4; i++) { const res = await fetch('https://api.example.com/dynamic-data'); console.log(`状态码: ${res.status}, 响应:`, await res.json()); } } testDynamicReply();
测试后清理
如果是在测试框架(如Jest)中使用,记得在测试结束后清除拦截规则,避免影响其他测试:
// 清除所有mock规则 mockAgent.reset(); // 或者恢复全局Dispatcher为默认 setGlobalDispatcher(new undici.Agent());
内容的提问来源于stack exchange,提问作者vanchagreen
相关产品推荐
相关产品推荐

