- Introduction
- Getting started
- Philosophy
- Comparison
- Limitations
- Debugging runbook
- FAQ
- Basics
- Concepts
- Network behavior
- Integrations
- API
- CLI
- Best practices
- Recipes
- Cookies
- Query parameters
- Response patching
- Polling
- Streaming
- Network errors
- File uploads
- Responding with binary
- Custom worker script location
- Global response delay
- GraphQL query batching
- Higher-order resolver
- Keeping mocks in sync
- Merging Service Workers
- Mock GraphQL schema
- Using CDN
- Using custom "homepage" property
- Using local HTTPS
- Vitest Browser Mode
Vitest Browser Mode
Integrate Mock Service Worker with Vitest Browser Mode.
Vitest Browser Mode is a fantastic tool for testing your UI components in the actual browser. There are a few things to consider when integrating MSW with the Browser Mode:
- As the name suggests, your Browser Mode tests run in the actual browser. This means you will be using the Browser integration of MSW (i.e.
setupWorker()
); - You cannot reuse the app-level integration (e.g. in your
main.tsx
) because you don’t normally render your entire component tree during component testing. You can still rely on that integration for local development with MSW though; - Vitest actually ships with MSW built-in, however, as of the time writing this, you cannot directly access the
worker
instance created by Vitest. This may change in the future.
Example
We recommend integrating MSW with Vitest Browser Mode by extending the test context.
// test-extend.ts
import { test as testBase } from 'vitest'
import { worker } from './mocks/browser.js'
export const test = testBase.extend({
worker: [
async ({}, use) => {
// Start the worker before the test.
await worker.start()
// Expose the worker object on the test's context.
await use(worker)
// Stop the worker after the test is done.
worker.stop()
},
{
auto: true,
},
],
})
Provide the auto: true
fixture option so MSW would affect the tests that
don’t reference the worker
fixture explicitly.
Initial request handlers
Any test()
now runs against the initial, happy-path request handlers (like those in handlers.ts
) without explicitly referencing MSW. Leverage this for cleaner test suites and predictable baseline behavior.
import { test } from './test-extend'
import { Dashboard } from './components/dashboard.js'
test('renders the dashboard', () => {
// Uses only the happy-path request handlers.
render(<Dashboard />)
// Your actions and assertions...
})
Overriding request handlers
You can override request handlers by accessing the worker
object of your test’s context and calling .use()
, providing it with the request handlers that should take priority:
import { http, HttpResponse } from 'msw'
import { test } from './test-extend'
import { Dashboard } from './components/dashboard.js'
test('displays a notification if fetching the dashboard failed', async ({
worker,
}) => {
// Prepend overrides to the happy-path handlers
// on the `worker` object from the test's context.
worker.use(
http.post('/dashboard', () => {
return new HttpResponse(null, { status: 500 })
}),
)
render(<Dashboard />)
// Your actions and assertions...
})