
升级 msw 到 2.x 后,jest 测试中 fetch 请求不再被拦截,根本原因是 msw 2 仅原生支持 node.js 内置 fetch,而 jest 默认使用 jsdom + whatwg-fetch 等浏览器环境 polyfill,导致请求绕过拦截。
升级 msw 到 2.x 后,jest 测试中 fetch 请求不再被拦截,根本原因是 msw 2 仅原生支持 node.js 内置 fetch,而 jest 默认使用 jsdom + whatwg-fetch 等浏览器环境 polyfill,导致请求绕过拦截。
MSW 2.0 是一次架构级重构,其核心设计原则是“与运行时深度对齐”——在浏览器中依赖原生 fetch 和 Request/Response,而在 Node.js 中则严格依赖 undici 提供的标准兼容实现。这意味着它主动放弃了对各类 fetch polyfill(如 whatwg-fetch、isomorphic-fetch)的兼容支持。当你在 Jest(默认启用 jsdom)中继续沿用旧版 polyfill,MSW 2 就无法挂载拦截器,最终请求直发网络,触发 TypeError: Failed to fetch 错误。
✅ 正确做法是:让 Jest 测试环境完全切换至 Node.js 原生 fetch 生态,而非适配浏览器 polyfill。以下是经过验证的迁移步骤:
1. 移除旧 polyfill
检查 package.json 和 jest.config.js,移除所有 whatwg-fetch、cross-fetch 等显式引入的 fetch polyfill,并卸载对应包:
npm uninstall whatwg-fetch # 或 yarn remove whatwg-fetch
2. 创建标准化 polyfill 文件(jest.polyfills.js)
该文件将 Node.js 标准全局对象注入 Jest 全局作用域,确保 MSW 2 能识别并接管请求:
// jest.polyfills.js
const { TextEncoder, TextDecoder } = require('node:util');
const { Blob } = require('node:buffer');
const { fetch, Request, Response, Headers, FormData } = require('undici');
// 注入全局标准接口(MSW 2 依赖这些)
globalThis.TextEncoder = TextEncoder;
globalThis.TextDecoder = TextDecoder;
globalThis.Blob = Blob;
globalThis.fetch = fetch;
globalThis.Request = Request;
globalThis.Response = Response;
globalThis.Headers = Headers;
globalThis.FormData = FormData;⚠️ 注意:undici 是 Node.js 官方推荐的现代 HTTP 客户端,需单独安装:
npm install undici --save-dev
3. 配置 Jest 加载 polyfill
在 jest.config.js 中指定初始化文件:
module.exports = {
setupFiles: ['./jest.polyfills.js'],
// 若已存在 setupFilesAfterEnv,确保 polyfill 在其之前执行
testEnvironment: 'node', // 强烈建议设为 'node'(非 'jsdom'),避免 DOM 环境干扰 fetch 行为
};4. 更新 MSW 处理器语法(可选但推荐)
确保你的 handler 使用 MSW 2 的新 API:
import { setupServer, http } from 'msw/node'; // 注意导入路径
const server = setupServer(
http.get('http://localhost:1800/users_info', ({ request }) => {
return HttpResponse.json({ userId: 123 });
})
);
// 测试前启动
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());? 验证是否生效
运行测试时观察控制台:若看到类似 MSW: captured a request to http://localhost:1800/users_info 日志,即表示拦截成功;若仍报 Failed to fetch,请检查:
- jest.polyfills.js 是否被正确加载(可在其中加 console.log('polyfill loaded') 验证);
- undici 版本 ≥ 5.27.0(低版本可能缺失 FormData 支持);
- 避免混用 msw/browser 和 msw/node —— Jest 环境必须使用 msw/node。
? 总结:MSW 2 并非“不兼容 Jest”,而是要求 Jest 环境向 Node.js 标准靠拢。这一转变提升了稳定性与可预测性,代价是需主动适配运行时环境。对于纯前端组件测试(需 jsdom),官方更推荐回退至 MSW 1.x 或采用 @mswjs/interceptors 等轻量替代方案。


















