import { http, HttpResponse } from "msw";
import { setupServer } from "msw/node";
const server = setupServer(
http.get("/api/user", () => HttpResponse.json({ name: "Ana" })),
);
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
Many teams prefer MSW (Mock Service Worker), because your real request code still runs and the tests survive refactors.
With jest.mock('./api') you replace your API module with mock functions. It's quick, but it has two problems:
- The test no longer runs your real request code. URLs, headers, JSON parsing and error handling are all skipped.
- The test knows which module the component imports. So refactoring the data layer, say moving to React Query, breaks the tests.
MSW intercepts requests at the network level:
- In Node it uses
setupServerfrommsw/node. - You declare handlers like
http.get('/api/user', () => HttpResponse.json({ name: 'Ana' })). - The component's real
fetchor axios code runs unchanged. - You can reuse the same handlers in the browser during development, and in Storybook.
So MSW tests are closer to production, and they survive refactors.
Module mocks are still fine for things like analytics or very slow third-party SDKs.
jest.mockreplaces the module, so your real request code is skipped.- Module mocks tie tests to the import structure, so refactors break them.
- MSW intercepts at the network level, so your real fetch code runs.
- MSW handlers can be reused across tests, development and Storybook.
- Module mocks are still fine for analytics or slow third-party SDKs.
Read more