单元测试中 Mock Fetch API 应用 jest.spyOn(global, 'fetch').mockImplementation() 并在 afterEach 中 mockRestore(),返回 new Response() 构造合法响应,支持按 URL/参数差异化返回,且每次测试后必须清理。

在单元测试中 Mock Fetch API,核心是替换全局 fetch 函数,让它返回可控的响应,而不是真正发网络请求。关键在于“不污染全局环境”“可复位”“支持多种响应场景”,而非简单地直接赋值 window.fetch = jest.fn()。
用 Jest.mock() 模拟全局 fetch(推荐)
Jest 提供了安全模拟全局函数的能力,避免手动覆盖和清理问题:
- 在测试文件顶部使用
jest.mock('node-fetch')(仅限 Node 环境);但浏览器环境更常用的是直接 mock 全局fetch - 更通用的做法:在
beforeEach中用jest.spyOn(global, 'fetch').mockImplementation(...),并在afterEach中调用mockRestore()复位 - 示例:
beforeEach(() => { global.fetch = jest.fn(); }); afterEach(() => { jest.clearAllMocks(); // 或 global.fetch.mockRestore(),如果用了 spyOn });
构造符合 Response 接口的 Mock 响应
Fetch 返回的是 Promise,Mock 时需返回合法的 Response 实例(或兼容对象),否则被测代码调用 .json()、.text() 会报错:
- 用
new Response(body, options)构造真实响应(Jest 默认环境支持) - 支持 JSON:
new Response(JSON.stringify({ ok: true }), { status: 200 }) - 支持错误响应:
new Response('Not Found', { status: 404 }) - 需要模拟网络失败?抛出异常:
global.fetch.mockRejectedValue(new Error('Network error'))
按请求 URL 或参数差异化响应
多个测试用例可能依赖不同接口返回不同数据,可通过检查 fetch 调用参数实现条件响应:
- 在
mockImplementation中读取第一个参数(URL)或第二个参数(options) - 示例:
global.fetch = jest.fn((url, options) => { if (url.includes('/api/users')) { return Promise.resolve(new Response(JSON.stringify([{ id: 1, name: 'Alice' }]))); } if (url === '/api/posts' && options?.method === 'POST') { return Promise.resolve(new Response(JSON.stringify({ id: 101 }), { status: 201 })); } return Promise.resolve(new Response('', { status: 404 })); });
配合 async/await 写断言更自然
被测函数通常是 async 的,测试中直接 await,再用 expect(fetch).toHaveBeenCalledWith(...) 验证调用是否符合预期:
- 验证请求是否发出:
expect(fetch).toHaveBeenCalledTimes(1) - 验证请求地址和方法:
expect(fetch).toHaveBeenCalledWith('/api/data', { method: 'GET' }) - 验证结果处理逻辑是否正确(比如状态更新、错误提示),而非只测 fetch 本身
不复杂但容易忽略的是:每次测试后必须清理 fetch Mock,否则会影响其他测试;同时优先使用 Response 构造器而非手写 mock 对象,保证与真实行为一致。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











