Mock Service Worker (MSW) 2.x for API mocking. Use when testing frontend components with network mocking, simulating API errors, or creating deterministic API responses in tests.
View on GitHubFebruary 4, 2026
Select agents to install to:
npx add-skill https://github.com/yonatangross/skillforge-claude-plugin/blob/main/plugins/ork-testing/skills/msw-mocking/SKILL.md -a claude-code --skill msw-mockingInstallation paths:
.claude/skills/msw-mocking/# MSW (Mock Service Worker) 2.x
Network-level API mocking for frontend tests using MSW 2.x.
## Quick Reference
```typescript
// Core imports
import { http, HttpResponse, graphql, ws, delay, passthrough } from 'msw';
import { setupServer } from 'msw/node';
// Basic handler
http.get('/api/users/:id', ({ params }) => {
return HttpResponse.json({ id: params.id, name: 'User' });
});
// Error response
http.get('/api/fail', () => {
return HttpResponse.json({ error: 'Not found' }, { status: 404 });
});
// Delay simulation
http.get('/api/slow', async () => {
await delay(2000);
return HttpResponse.json({ data: 'response' });
});
// Passthrough (NEW in 2.x)
http.get('/api/real', () => passthrough());
```
## Test Setup
```typescript
// vitest.setup.ts
import { beforeAll, afterEach, afterAll } from 'vitest';
import { server } from './src/mocks/server';
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
```
## Runtime Override
```typescript
import { http, HttpResponse } from 'msw';
import { server } from '../mocks/server';
test('shows error on API failure', async () => {
server.use(
http.get('/api/users/:id', () => {
return HttpResponse.json({ error: 'Not found' }, { status: 404 });
})
);
render(<UserProfile id="123" />);
expect(await screen.findByText(/not found/i)).toBeInTheDocument();
});
```
## Anti-Patterns (FORBIDDEN)
```typescript
// ❌ NEVER mock fetch directly
jest.spyOn(global, 'fetch').mockResolvedValue(...)
// ❌ NEVER mock axios module
jest.mock('axios')
// ❌ NEVER test implementation details
expect(fetch).toHaveBeenCalledWith('/api/...')
// ✅ ALWAYS use MSW
server.use(http.get('/api/...', () => HttpResponse.json({...})))
// ✅ ALWAYS test user-visible behavior
expect(await screen.findByText('Success')).toBeInTheDocument()
```
## Key Decisions
| Decision | Recommendation |
|----------|----------------|
| Handler location | `src/mocks