推荐使用 Mock Service Worker(MSW),它通过 Service Worker 拦截 fetch 请求,支持浏览器和 Node.js,无需修改业务代码,开发体验最接近真实 API。

在 JS 项目中做 Fetch 请求的 Mock,核心是拦截原生 fetch 调用并返回预设响应,而不是改业务代码或依赖后端服务。推荐用 Mock Service Worker(MSW),它轻量、与框架无关、支持真实请求路径匹配和动态响应逻辑,开发体验最接近真实 API。
用 MSW 快速搭建 Fetch Mock 环境
MSW 在浏览器中通过 Service Worker 拦截网络请求,对 fetch 和 XMLHttpRequest 都生效,无需修改任何已有请求代码。
- 安装:
npm install msw --save-dev - 创建 mock handlers(如
mocks/handlers.js):import { rest } from 'msw'; export const handlers = [ rest.get('/api/users', (req, res, ctx) => { return res( ctx.status(200), ctx.json([{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]) ); }), rest.post('/api/login', (req, res, ctx) => { const { username } = req.body; return username === 'admin' ? res(ctx.status(200), ctx.json({ token: 'fake-jwt' })) : res(ctx.status(401), ctx.json({ error: 'Invalid credentials' })); }) ]; - 配置 Service Worker(
mocks/browser.js):import { setupWorker } from 'msw'; import { handlers } from './handlers'; export const worker = setupWorker(...handlers); - 在入口文件(如
index.js或main.js)中启动:if (process.env.NODE_ENV === 'development') { const { worker } = require('./mocks/browser'); worker.start({ onUnhandledRequest: 'bypass' }); }
不引入新库:手动重写 window.fetch(适合简单场景)
若项目极轻量或仅需临时调试,可直接在测试/开发环境覆盖全局 fetch,但注意仅限非生产环境且需谨慎清理。
- 定义 mock 映射表:
const mockResponses = { 'GET:/api/profile': { id: 123, name: 'Tom' }, 'POST:/api/submit': { success: true } }; - 重写 fetch:
const originalFetch = window.fetch; window.fetch = async (input, init = {}) => { const method = (init.method || 'GET').toUpperCase(); const key = `${method}:${typeof input === 'string' ? input : input.url}`; if (mockResponses[key]) { return Promise.resolve({ ok: true, status: 200, json: () => Promise.resolve(mockResponses[key]) }); } return originalFetch(input, init); }; - 务必在测试结束或页面卸载时还原:
window.fetch = originalFetch
配合测试:在 Jest 中使用 MSW 或 jest-fetch-mock
单元测试中更倾向使用纯 JS 方案,避免 Service Worker 的异步注册开销。
-
jest-fetch-mock更简单直接:安装后在 setup 文件中启用,然后用fetch.mockResponse()控制返回值 - MSW 也支持 Node 环境(搭配
node-server),但浏览器模式已足够覆盖大多数前端测试场景 - 关键技巧:为每个测试用例单独设置 mock 响应,避免测试间污染
注意事项和常见避坑点
Mock 不是万能胶,几个容易出问题的地方要留心:
- Service Worker 需要 HTTPS 或
localhost才能注册;本地开发用localhost没问题,但127.0.0.1可能失败 - MSW 默认会警告未匹配的请求;设
onUnhandledRequest: 'bypass'可让未 mock 的请求透传到真实网络 - 不要在生产构建中打包 mock 代码——用环境变量或 webpack 的
DefinePlugin剔除 - Mock 响应体类型(JSON / text / blob)要和真实接口一致,否则业务中
.json()或.text()可能报错











