From harness-claude
Intercepts HTTP requests in tests using Mock Service Worker (MSW) handlers at the network level. Useful for mocking API responses, simulating errors or delays, and sharing mocks between tests and development.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:test-msw-patternThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Intercept HTTP requests in tests using Mock Service Worker handlers at the network level
Intercept HTTP requests in tests using Mock Service Worker handlers at the network level
npm install -D msw
// test/mocks/handlers.ts
import { http, HttpResponse } from 'msw';
export const handlers = [
http.get('/api/users', () => {
return HttpResponse.json([
{ id: '1', name: 'Alice', email: '[email protected]' },
{ id: '2', name: 'Bob', email: '[email protected]' },
]);
}),
http.get('/api/users/:id', ({ params }) => {
return HttpResponse.json({
id: params.id,
name: 'Alice',
email: '[email protected]',
});
}),
http.post('/api/users', async ({ request }) => {
const body = await request.json();
return HttpResponse.json({ id: 'new-id', ...body }, { status: 201 });
}),
];
// test/mocks/server.ts
import { setupServer } from 'msw/node';
import { handlers } from './handlers';
export const server = setupServer(...handlers);
// test/setup.ts
import { server } from './mocks/server';
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
import { http, HttpResponse } from 'msw';
import { server } from './mocks/server';
it('shows error state when API fails', async () => {
server.use(
http.get('/api/users', () => {
return HttpResponse.json(
{ message: 'Internal server error' },
{ status: 500 },
);
}),
);
render(<UserList />);
expect(await screen.findByText('Failed to load users')).toBeInTheDocument();
});
import { delay, http, HttpResponse } from 'msw';
server.use(
http.get('/api/users', async () => {
await delay(2000);
return HttpResponse.json([]);
})
);
http.post('/api/users', async ({ request, params, cookies }) => {
const body = await request.json();
const authHeader = request.headers.get('Authorization');
if (!authHeader) {
return HttpResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
return HttpResponse.json({ id: 'new', ...body }, { status: 201 });
}),
it('sends correct headers', async () => {
let capturedHeaders: Headers;
server.use(
http.get('/api/users', ({ request }) => {
capturedHeaders = request.headers;
return HttpResponse.json([]);
})
);
await fetchUsers();
expect(capturedHeaders!.get('Accept')).toBe('application/json');
});
MSW intercepts requests at the network level, below fetch and XMLHttpRequest. This means your application code is completely unmodified — no dependency injection, no mock modules, no test-specific code paths.
MSW v2 (current): Uses standard Request/Response objects from the Fetch API. Handlers use http.get(), http.post(), etc. Response construction uses HttpResponse.json(), HttpResponse.text(), etc.
onUnhandledRequest: 'error': Causes tests to fail if the code makes an HTTP request that no handler matches. This catches missing mocks and unintended API calls.
Handler precedence: Handlers added with server.use() (per-test overrides) take priority over handlers passed to setupServer() (defaults). server.resetHandlers() removes per-test overrides, restoring defaults.
Browser vs Node: MSW has two modes:
setupServer() — for Node.js test environments (Vitest, Jest)setupWorker() — for browser environments (development server, Storybook)Same handlers work in both modes.
Trade-offs:
onUnhandledRequest: 'error' catches missing mocks — but requires handlers for every request, including static assets in browser modenpx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeProvides MSW v2 best practices for setting up handlers, mocking REST/GraphQL APIs, and integrating mocks into test environments. Activated when working with MSW or HTTP API mocking.
Creates mock APIs and services for testing using MSW, Nock, or custom mock servers, with typed factories and request interception patterns.
Mocks APIs with MSW for testing Umbraco backoffice extensions, enabling error handling, loading states, and edge cases without a running Umbraco instance.