MSW(Mock Service Worker):API 模拟工具的核心优势与使用指南
MSW(Mock Service Worker) 是一个用于浏览器和 Node.js 的 API 模拟工具,它通过 Service Worker 拦截网络请求,允许开发者在无需修改代码的情况下模拟后端 API 的响应。MSW 支持 REST 和 GraphQL,适用于开发、测试和调试场景。
MSW 的核心优势
- 无侵入性
通过 Service Worker 拦截请求,无需修改业务代码或配置代理。 - 贴近真实网络行为
模拟的请求与实际 HTTP 请求行为一致(包括 Headers、CORS、延迟等)。 - 多环境支持
可在浏览器(开发环境)和 Node.js(测试环境)中使用同一套 Mock 配置。 - 类型安全
支持 TypeScript,提供清晰的 API 和错误提示。 - 灵活的场景模拟
动态响应、错误状态、延迟、条件匹配等功能一应俱全。
快速上手 MSW
1. 安装
npm install msw --save-dev
# 浏览器环境需额外安装 Service Worker
npx msw init public/ --save
2. 定义 Mock Handlers
创建 src/mocks/handlers.js
:
import { rest } from 'msw';
export const handlers = [
// 模拟 GET 请求
rest.get('/api/user', (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({ name: 'Alice', age: 30 })
);
}),
// 模拟 POST 请求
rest.post('/api/login', async (req, res, ctx) => {
const { username } = await req.json();
return res(
ctx.delay(1000), // 模拟 1s 延迟
ctx.json({ token: 'mock-token' })
);
}),
// 模拟 GraphQL 请求
import { graphql } from 'msw';
graphql.query('GetUser', (req, res, ctx) => {
return res(
ctx.data({ user: { id: '1', name: 'Bob' } })
);
})
];
3. 配置 Service Worker
创建 src/mocks/browser.js
:
import { setupWorker } from 'msw';
import { handlers } from './handlers';
export const worker = setupWorker(...handlers);
4. 启动 Mock 服务(开发环境)
在应用入口文件(如 src/index.js
)中:
if (process.env.NODE_ENV === 'development') {
const { worker } = require('./mocks/browser');
worker.start();
}
MSW 高级用法
1. 动态响应与条件匹配
rest.get('/api/data', (req, res, ctx) => {
const { searchParams } = req.url;
const query = searchParams.get('q');
if (query === 'error') {
return res(ctx.status(500));
}
return res(ctx.json({ results: [] }));
});
2. 错误模拟
rest.get('/api/fail', (req, res, ctx) => {
return res(
ctx.status(404),
ctx.json({ error: 'Not Found' })
);
});
3. 文件上传模拟
rest.post('/api/upload', async (req, res, ctx) => {
const file = await req.body.get('file');
return res(ctx.json({ url: 'https://mock-url' }));
});
4. 与测试框架集成(如 Jest/Vitest)
创建 src/mocks/server.js
(Node.js 环境):
import { setupServer } from 'msw/node';
import { handlers } from './handlers';
export const server = setupServer(...handlers);
在测试文件中:
import { server } from './mocks/server';
// 启动 Mock 服务
beforeAll(() => server.listen());
// 重置 Handlers
afterEach(() => server.resetHandlers());
// 关闭服务
afterAll(() => server.close());
// 测试示例
test('fetches user data', async () => {
const response = await fetch('/api/user');
const data = await response.json();
expect(data.name).toBe('Alice');
});
MSW 的适用场景
-
前端开发阶段
- 后端 API 尚未完成时,快速实现前端逻辑。
- 模拟异常场景(如网络错误、超时)。
-
自动化测试
- 在单元测试或 E2E 测试中隔离外部依赖。
- 确保测试的稳定性和可重复性。
-
演示与原型开发
- 快速构建功能演示,无需真实后端支持。
MSW 与其他 Mock 工具对比
工具 | 核心机制 | 优势 | 局限性 |
---|---|---|---|
MSW | Service Worker | 无侵入性、支持多环境、类型安全 | 需浏览器支持 Service Worker |
json-server | 本地 JSON 文件 | 快速启动、支持完整 REST API | 功能简单,无法模拟复杂逻辑 |
axios-mock-adapter | 覆写 axios 实例 | 轻量级、易集成 | 仅限 axios,无法覆盖原生 fetch |
Puppeteer | 浏览器自动化 | 支持真实浏览器行为 | 配置复杂,适合 E2E 测试 |
注意事项
-
Service Worker 注册
- 确保浏览器环境中 Service Worker 正确注册(通过
npx msw init
生成文件)。 - 开发服务器需托管静态文件(如 Vite、Webpack 的
public
目录)。
- 确保浏览器环境中 Service Worker 正确注册(通过
-
请求拦截优先级
- Service Worker 的拦截优先级高于其他工具(如
fetch
全局覆写)。
- Service Worker 的拦截优先级高于其他工具(如
-
浏览器兼容性
- 不支持 IE11 等旧浏览器(依赖 Service Worker 和现代 JavaScript API)。
总结
MSW 通过 Service Worker 提供了一种高效、真实的 API 模拟方案,尤其适合复杂项目的前后端分离开发和自动化测试。其无侵入性和多环境支持使其成为现代 Web 开发的强力工具。若你的项目需要灵活控制 Mock 数据,或希望在测试中精准模拟网络行为,MSW 是一个值得投入的解决方案。