Introduction
MSW (Mock Service Worker) lets you intercept network requests at the browser or Node.js level without modifying your application code. This approach delivers more realistic tests than traditional library mocks. In 2026, MSW has become essential for teams that want to guarantee the reliability of their API integrations. This intermediate tutorial walks you through a professional setup step by step.
Prerequisites
- Node.js 20+
- Basic knowledge of TypeScript and testing (Vitest or Jest)
- An existing React or Next.js project
Installing MSW
npm install msw --save-dev
npx msw init ./publicThis command installs MSW and generates the worker file in the public folder for browser request interception.
Creating the handlers
import { http, HttpResponse } from 'msw';
export const handlers = [
http.get('/api/users', () => {
return HttpResponse.json([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]);
}),
http.post('/api/users', async ({ request }) => {
const newUser = await request.json();
return HttpResponse.json(newUser, { status: 201 });
}),
];Handlers define the mocked responses. They are reusable across tests and the development environment.
Browser worker configuration
import { setupWorker } from 'msw/browser';
import { handlers } from './handlers';
export const worker = setupWorker(...handlers);This file initializes the Service Worker that will intercept requests in the browser during development.
Server configuration for tests
import { setupServer } from 'msw/node';
import { handlers } from './handlers';
export const server = setupServer(...handlers);The Node version lets you use the same handlers in Jest or Vitest tests without a browser.
Integration in tests
import { server } from '../mocks/server';
import { http, HttpResponse } from 'msw';
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
test('récupère la liste des utilisateurs', async () => {
const res = await fetch('/api/users');
const data = await res.json();
expect(data).toHaveLength(2);
});The listen/reset/close cycle ensures a clean environment between each test.
Best practices
- Centralize all handlers in a single file for easier maintenance
- Use dynamic scenarios with environment variables
- Avoid overly generic mocks that hide real API contracts
- Document each handler with possible error statuses
- Combine MSW with tools like MSW Data to generate realistic data
Common mistakes to avoid
- Forgetting to call server.resetHandlers() between tests
- Defining handlers with absolute URLs instead of relative ones
- Not handling network errors (status 500) in test scenarios
- Leaving the worker active in production
Going further
Discover our advanced training on modern testing and professional mocking at Learni Group.