Introduction
Mock Service Worker (MSW) is a powerful tool that intercepts HTTP requests at the browser level using Service Workers. It lets you simulate API responses without modifying your application code. Ideal for frontend development, testing, and offline demos, MSW boosts productivity by removing reliance on a real backend. This tutorial shows you how to integrate it cleanly into a modern TypeScript project.
Prerequisites
- Node.js 18 or higher
- Basic knowledge of JavaScript/TypeScript
- An existing React or Next.js project
- npm or yarn installed
Installing MSW
npm install msw --save-dev
npx msw init ./publicThis command installs MSW and generates the worker file in the public folder. The worker is essential for intercepting requests in the browser.
Creating 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 routes. Each handler matches an HTTP method and path, returning a realistic simulated response.
Configuring the MSW Server
import { setupServer } from 'msw/node';
import { handlers } from './handlers';
export const server = setupServer(...handlers);This file sets up the MSW server for Node.js tests. It is used in testing environments such as Jest or Vitest.
Integrating into the Application
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
async function enableMocking() {
if (process.env.NODE_ENV === 'development') {
const { worker } = await import('./mocks/browser');
await worker.start();
}
}
enableMocking().then(() => {
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
});The worker starts only in development. This ensures mocks do not interfere with production environments.
Test Example with MSW
import { render, screen } from '@testing-library/react';
import App from './App';
import { server } from './mocks/server';
import { http, HttpResponse } from 'msw';
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
test('affiche la liste des utilisateurs', async () => {
render(<App />);
expect(await screen.findByText('Alice')).toBeInTheDocument();
});This test verifies that the app correctly consumes the mocked data. Handlers can be overridden per test for specific scenarios.
Best Practices
- Place your handlers in a dedicated src/mocks folder
- Use HttpResponse for typed and realistic responses
- Enable mocks only in development
- Write tests that reset handlers between each case
- Document mocked endpoints for the team
Common Mistakes to Avoid
- Forgetting to call worker.start() or server.listen()
- Using absolute paths instead of relative paths
- Not resetting handlers between tests
- Leaving mocks enabled in production
Going Further
Explore advanced features such as dynamic scenarios and Playwright integration. Check out our Learni courses.