单元测试中mock全局fetch的核心是替换或拦截global.fetch使其返回可控响应,需在测试前mock、测试后restore,并注意环境适配与调用链一致性。

在单元测试中 Mock 全局 fetch,核心是**替换或拦截全局 window.fetch(或 global.fetch),使其返回可控的响应,同时不干扰其他测试**。关键在于 mock 的时机、作用域和还原方式。
用 jest.mock() 模拟全局 fetch(推荐)
Jest 提供了直接 mock 全局函数的能力。由于 fetch 是全局变量,不能像普通模块那样用 jest.mock('node-fetch'),但可以用 jest.mock 配合 global 手动实现:
- 在测试文件顶部(或
beforeAll中)执行:global.fetch = jest.fn(); - 为每次测试设置期望行为:
fetch.mockResolvedValue(new Response(JSON.stringify({ ok: true }), { status: 200 })); - 测试结束后务必清理:
fetch.mockRestore();(放在afterEach或afterAll)
封装可复用的 mock 工具函数
避免重复写 mockResolvedValue 和 Response 构造,可以封装一个 helper:
function mockFetch(json, status = 200) {<br> fetch.mockResolvedValue(new Response(JSON.stringify(json), { status }));<br>}- 调用:
mockFetch({ data: 'test' }, 201); - 也支持 mock error:
fetch.mockRejectedValue(new Error('Network failed'));
注意 fetch 的调用链与类型安全
真实 fetch 返回 Promise<response></response>,而 Response.json() 是另一个 Promise。Mock 时要保持链式调用一致:
- 如果业务代码写了
await (await fetch(url)).json(),mock 必须让.json()可调用:fetch.mockResolvedValue({<br> json: jest.fn().mockResolvedValue({ ok: true })<br>} as unknown as Response); - 更稳妥的方式是使用
jest.requireActual('node-fetch')(仅 Node 环境)或构造真实Response实例(现代 Jest 支持)
在不同环境中的适配要点
浏览器环境(JSDOM)和 Node 环境行为略有差异:
- JSDOM 默认提供
window.fetch,mock 时操作global.fetch或window.fetch均可,但统一用global.fetch更稳定 - Node 环境需先安装
node-fetch并手动挂载:global.fetch = require('node-fetch');,再 mock - 若用
msw(Mock Service Worker),则无需 mockfetch,而是拦截网络请求——适合 E2E 或集成测试,但单元测试中略重
不复杂但容易忽略:mock 后记得验证调用次数和参数,比如 expect(fetch).toHaveBeenCalledWith('/api/user', expect.any(Object)),才能真正保障逻辑正确性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











