- Introduction
- Quick start
- Philosophy
- Comparison
- Default behaviors
- Limitations
- Debugging runbook
- FAQ
- Mocking HTTP
- Mocking GraphQL
- Mocking WebSocket
- Integrations
- API
- CLI
- Best practices
- Recipes
Mocking responses
Declaring and using mocked responses.
Responding to an intercepted request with a mocked response is one of the most common use cases for MSW. Note that it isn’t the only way to handle a request. This page will give you an overview of how to create mocked responses and use them in your request handlers.
Fetch API limitations
When working with MSW, you will be using Fetch API Response
instances to describe mocked responses. Relying on a web standard allows for a familiar and flexible mocking experience, reusing of the existing network utilities, and transferable knowledge.
While you always write your mocks from the server’s perspective, the Fetch API isn’t designed to declare server responses. The API contains several restrictions that make sense on the client but less so in your mocks:
- Some response headers, like
Set-Cookie
, are forbidden; - Setting status codes outside of the
2xx
-5xx
range are forbidden;
None of these restrictions apply when mocking responses with MSW. You can mock cookies, set otherwise non-configurable status codes, like 101 Switching Protocols
, and declare mocked responses as you would server responses. That is achieved by using the HttpResponse
superset class provided by the library. Please prefer using it when declaring mocked responses.
Responding to requests
Return a mocked response
You can respond to an intercepted request with a mocked response by constructing the Fetch API Response
instance you want and returning it from the response resolver.
import { http, HttpResponse } from 'msw'
export const handlers = [
http.get<never, never, string>('/resource', () => {
return HttpResponse.text('hello world')
}),
]
You can return a plain Fetch API
Response
instance, too. It’s recommended to use theHttpResponse
class instead, which is a drop-in replacement forResponse
but provides improved developer experience and unlocks otherwise unavailable features, like mocking theset-cookie
header.
Throw a mocked response
If you throw a Response
instance at any point in the response resolver, that response will be used as the mocked response for the request. This is particularly handy for short-circuiting the resolver flow anywhere during the request handling.
function withAuthorization(request: Request) {
if (!request.headers.get('authorization')) {
throw HttpResponse.text('Unauthorized', { status: 401 })
}
}
http.get<never, never, { id: string }>('/resource', ({ request }) => {
withAuthorization(request)
return HttpResponse.json({ id: 'abc-123' })
})
In this example, the
GET /resource
request will get a “401 Unauthorized” response if it doesn’t contain theAuthorization
header. Otherwise, it will proceed with the mocked JSON response.
Response declaration
It is highly recommended you get yourself familiar with Fetch API Response
class. Mocking various response scenarios will come down to declaring them using that standard class. Below, you can find a few common examples. Make sure to explore the section to your left for more advanced use cases.
Status code
http.get('/resource', () => {
return new HttpResponse(null, { status: 404 })
})
Response headers
http.get('/resource', () => {
return HttpResponse.json(
{ id: 'abc-123' },
{
headers: {
'content-type': 'application/hal+json',
},
},
)
})
Response body
You can use all the supported response body types, like strings, Blob
, ArrayBuffer
, FormData
, URLSearchParams
, and ReadableStream
as the body of your mocked response.
http.get('/resource', () => {
return HttpResponse.text('hello world')
})
Learn more about the static shorthand methods like
.text()
,.json()
, and others in theHttpResponse
API reference.
Next steps
Please explore the “Mocking HTTP” section for more recipes and advanced mocking scenarios. Here are a few noteworthy ones: