Quick start

Get MSW up and running in under five minutes.

This guide will take you through the barebones setup of MSW for intercepting HTTP requests in your Node.js tests with Vitest.

1. Installation

npm i msw --save-dev

2. Request handlers

Import the http namespace from the msw package and create your first request handler. Those are functions responsible for intercepting requests and handling their responses.

Let’s define a request handler for a GET https://api.example.com/user request:

// src/mocks/handlers.ts
import { http, HttpResponse } from 'msw'
 
export const handlers = [
  http.get('https://api.example.com/user', () => {
    return HttpResponse.json({
      id: 'abc-123',
      firstName: 'John',
      lastName: 'Maverick',
    })
  }),
]

MSW supports intercepting both HTTP, GraphQL, and WebSocket APIs.

3. Process-level integration

One of the core benefits of MSW is the ability to reuse the same mocks (e.g. handlers.ts) across different tools and environments. On their own, request handlers don’t do anything. They have to be provided to the setupServer or setupWorker functions to configure API mocking in a Node.js or a browser process, respectively.

Since Vitest tests run in a Node.js process, let’s use setupServer from msw/node and create a node.ts integration point:

// src/mocks/node.ts
import { setupServer } from 'msw/node'
import { handlers } from './handlers.js'
 
export const server = setupServer(...handlers)

This integration has nothing specific to Vitest. You can reuse it to apply MSW to any Node.js process.

4. Tool-level integration

At this step, you find the appropriate place to enable API mocking in your Node.js process. In the case of Vitest, that place is the test setup file, which runs before your tests. Open that file (or create it) and call server.listen() in enable mocking as follows:

// vitest.setup.ts
import { beforeAll, afterEach, afterAll } from 'vitest'
import { server } from './mocks/node.js'
 
beforeAll(() => server.listen())
afterEach(() => server.resetHandlers())
afterAll(() => server.close())

Make sure you have the vitest.setup.ts module listed in the test.setupFiles array in your vitest.config.ts.

5. Run tests

Once MSW is integrated into your Vitest setup, it will control the network as defined in your handlers.

// test/example.test.ts
// @vitest-environment node
import { test, expect } from 'vitest'
 
test('responds with the user', async () => {
  const response = await fetch('https://api.example.com/user')
 
  await expect(response.json()).resolves.toEqual({
    id: 'abc-123',
    firstName: 'John',
    lastName: 'Maverick',
  })
})
npx vitest
 ✓ test/example.test.ts (1 test) 1ms
   ✓ responds with the user 0ms

 Test Files  1 passed (1)
      Tests  1 passed (1)
   Start at  12:15:23
   Duration  166ms (transform 19ms, setup 0ms, collect 7ms, tests 1ms, environment 0ms, prepare 43ms)

Usage examples

MSW applies on the environment level (Node.js or browser). Integrating it with different tools will come down to finding the appropriate environment entrypoint provided to you by that tool and following the same setup as you did above.

For reference, we’ve prepared a curated collection of usage examples:

Usage examples

Examples of Mock Service Worker usage with various frameworks and libraries.

Next steps

This guide is a good starting point but you can do so much more with the library. We highly encourage you to explore this documentation to learn more about the capabilities of MSW. Here are some great topics to follow up on:

Need help?

Starting with a new tool can be difficult but you don’t have go through that alone. Whenever you encounter an issue, the best place to go is our Debugging runbook:

Debugging runbook

Steps to debug common issues with the library.

We are always happy to help you with any questions you might have. There are multiple ways you can reach out to us or other community members to get help:

And remember, there is always a person who’s one problem behind you. Be kind and offer help when you can.