一键导入
msw-fetch-mock
msw-fetch-mock 套件使用指南(搭配 MSW v2 + Vitest)。當需要 mock HTTP 請求、測試 fetch 呼叫、驗證 API 互動時使用。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
msw-fetch-mock 套件使用指南(搭配 MSW v2 + Vitest)。當需要 mock HTTP 請求、測試 fetch 呼叫、驗證 API 互動時使用。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
cubejs (Rubik's Cube solver, Kociemba two-phase) 使用指南。當需要實作魔術方塊自動解法、狀態字串序列化、或 scramble 產生時使用。
React 19 最佳實踐指南。當需要撰寫 React 元件、使用 Hooks、處理狀態管理、或搭配 TypeScript/Vite 開發時使用。
React Three Fiber (R3F) + Three.js + drei 最佳實踐。當需要建立 3D 場景、處理相機/光照、互動事件、動畫、效能優化時使用。
TDD (Test-Driven Development) 最佳實踐指南,搭配 Vitest + React Testing Library。當需要撰寫測試、實踐 Red-Green-Refactor、設計測試結構時使用。應在開發新功能時主動套用。
Test Doubles 最佳實踐指南(Vitest + TypeScript)。當需要選擇 Mock/Stub/Fake/Spy/Dummy、或討論測試隔離策略時使用。
Vite 6/7 最佳實踐指南。當需要初始化 Vite 專案、設定 plugin、配置 build、除錯 HMR、path alias 或整合 React/TS/Vitest 時使用。
| name | msw-fetch-mock |
| description | msw-fetch-mock 套件使用指南(搭配 MSW v2 + Vitest)。當需要 mock HTTP 請求、測試 fetch 呼叫、驗證 API 互動時使用。 |
msw-fetch-mock是jest-fetch-mock風格 API 的 MSW 相容層,讓習慣fetchMock.mockResponseOnce的人也能享受 MSW 的 service-worker 攔截能力。若無舊測試包袱,建議直接用原生 MSW v2httphandlers。
pnpm add -D msw msw-fetch-mock
MSW v2 需 Node 18+、TypeScript 5.0+。
src/test/mocks/server.ts:
import { setupServer } from 'msw/node'
import { http, HttpResponse } from 'msw'
export const handlers = [
http.get('/api/user', () => HttpResponse.json({ id: 1, name: 'Alice' })),
]
export const server = setupServer(...handlers)
src/test/setup.ts:
import { beforeAll, afterEach, afterAll } from 'vitest'
import { server } from './mocks/server'
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
afterEach(() => server.resetHandlers())
afterAll(() => server.close())
| v1 | v2 |
|---|---|
rest.get(url, (req, res, ctx) => res(ctx.json(data))) | http.get(url, () => HttpResponse.json(data)) |
ctx.status(500) | new HttpResponse(null, { status: 500 }) |
req.body | await request.json() / await request.text() |
http.post('/api/solve', async ({ request }) => {
const { facelets } = await request.json() as { facelets: string }
if (facelets.length !== 54) {
return HttpResponse.json({ error: 'invalid' }, { status: 400 })
}
return HttpResponse.json({ solution: "R U R' U'" })
})
import fetchMock from 'msw-fetch-mock'
beforeEach(() => fetchMock.resetMocks())
it('handles user fetch', async () => {
fetchMock.mockResponseOnce(JSON.stringify({ id: 1 }))
const res = await fetch('/api/user').then(r => r.json())
expect(res).toEqual({ id: 1 })
})
// 動態回應
fetchMock.mockResponse(async (req) => {
if (req.url.includes('/error')) return { status: 500, body: 'fail' }
return JSON.stringify({ ok: true })
})
import { server } from '@/test/mocks/server'
import { http, HttpResponse } from 'msw'
it('shows error on 500', async () => {
server.use(
http.get('/api/user', () => new HttpResponse(null, { status: 500 })),
)
// ... 測試錯誤行為
})
// afterEach 會 resetHandlers 還原
MSW 本身不像 jest-fetch-mock 直接給 call history,需自己 spy:
const requestSpy = vi.fn()
server.use(
http.post('/api/solve', async ({ request }) => {
requestSpy(await request.json())
return HttpResponse.json({ solution: 'R' })
}),
)
// ... 執行動作
expect(requestSpy).toHaveBeenCalledWith({ facelets: 'UUU...' })
// src/mocks/browser.ts
import { setupWorker } from 'msw/browser'
import { handlers } from './handlers'
export const worker = setupWorker(...handlers)
// main.tsx
if (import.meta.env.DEV) {
const { worker } = await import('./mocks/browser')
await worker.start()
}
首次要 npx msw init public/ --save 產生 service worker 檔。
'error' 讓漏掉的 request 測試失敗。undici 或 Node 18+:舊 Node 會出怪錯。request.json() 是 async。HttpResponse.json()。setupServer(Node),不用 setupWorker(browser)。魔術方塊網站大部分運算 client 側,API 可能只有:
對這些 endpoint 用 MSW mock,讓教學流程/上傳流程的 integration test 不靠真 server。