Mocking responses

Learn how to mock HTTP responses.

Basics

Mock Service Worker respects the WHATWG Fetch API specification, which means that the mocked responses you construct are the same responses you would receive when making a fetch call. If you are comfortable with the Response class, you can skip everything past this section—you know how to declare responses already.

To respond to an intercepted request, return a valid Response instance from the matching request handler:

import { http } from 'msw'
 
export const handlers = [
  // Intercept the "GET /resource" request.
  http.get('/resource', () => {
    // And respond with a "text/plain" response
    // with a "Hello world!" text response body.
    return new Response('Hello world!')
  }),
]

You don’t need to import the Response class because it’s a part of the global Fetch API in the browser and moden versions of Node.js (v17+). The library supports any variations of the Response instances, including shorthand responses created via methods like Response.json() or Response.error().

Using HttpResponse class

Although you can ues plain Fetch API responses, it’s highly recommended you use the custom HttpResponse class provided by the library. There are two reasons to prefer HttpResponse over the native Response:

  1. The HttpResponse class encapsulates useful shorthand methods for declaring responses, like HttpResponse.json(), HttpResponse.xml(), HttpResponse.formData(), etc.
  2. Unlike the native Response class, the HttpResponse class enables support for mocking response cookies by setting the Set-Cookie header on the mocked response.

Here’s the same GET /resource handler but using the HttpResponse class:

// 1. Import the "HttpResponse" class from the library.
import { http, HttpResponse } from 'msw'
 
export const handlers = [
  http.get('/resource', () => {
    // 2. Return a mocked "Response" instance from the handler.
    return HttpResponse.text('Hello world!')
  }),
]

HttpResponse is 100% compatible with the native Response class. Under the hood, HttpResponse returns a plain Fetch API Response instance.

Mocking status code and text

Provide the status and/or statusText property in the response initializer object to specify a mocked response status or response status code, respectively.

import { http, HttpResponse } from 'msw'
 
export const handlers = [
  http.get('/apples', () => {
    return new HttpResponse(null, {
      status: 404,
      statusText: 'Out Of Apples',
    })
  }),
]

Mocking headers

Provide the headers property in the response initializer object to specify mocked response headers.

import { http, HttpResponse } from 'msw'
 
export const handlers = [
  http.post('/auth', () => {
    return new HttpResponse(null, {
      headers: {
        'Set-Cookie': 'mySecret=abc-123',
        'X-Custom-Header': 'yes',
      },
    })
  }),
]

Learn more about constructing Headers.

Mocking body

You can respond to requests with various response body types: String, Blob, FormData, ReadableStream, and others (see Fetch API Response for supported response body types).

Below, let’s take a look at how to mock some of the most common HTTP response bodies.

Text responses

The most basic response in HTTP is a text response. Provide the text string you wish to respond with as an argument to the HttpResponse constructor to create a mocked text response:

import { http, HttpResponse } from 'msw'
 
export const handler = [
  http.get('/name', () => {
    return new HttpResponse('John')
  }),
]

You can also use HttpResponse.text() shorthand static method.

JSON responses

A much more common response body type is JSON. Provide the JSON you wish to respond with as an argument to the HttpResponse.json() statis method to create a mocked JSON response:

import { http, HttpResponse } from 'msw'
 
export const handlers = [
  http.post('/auth', () => {
    // Note that you DON'T have to stringify the JSON!
    return HttpResponse.json({
      user: {
        id: 'abc-123',
        name: 'John Maverick',
      },
    })
  }),
]

We recommend using the HttpResponse.json() shorthand static method to automatically keep the Content-Type and Content-Length response headers in-sync with the response JSON body you’re using.

Stream responses

You can respond with a ReadableStream to stream any data back to the client.

Streaming

Respond with a `ReadableStream`.

Other responses

There are many other response body types you can describe with MSW, like XML, Blob, ArrayBuffer, or FormData. Please refer to the HttpResponse API to learn more about using other response body types.

HttpResponse

API reference for the `HttpResponse` class.

Mocking error responses

Construct and return a valid error response from a response resolver to emulate an error response.

http.get('/user', () => {
  // Respond with "401 Unauthorized" to "GET /user" requests.
  return new HttpResponse(null, { status: 401 })
})

Mocking network errors

Use the Response.error() or HttpResponse.error() static method to raise a network error. Unlike an error response, a network error will halt the request execution and will mark that request as failed. In practice, you may experience network errors when constructing an invalid request or requesting hostnames that cannot be resolved.

http.post('/checkout/cart', () => {
  return HttpResponse.error('Failed to save the cart')
})

Note that it’s up to the request client you’re using to display the custom network error messages. Some clients will while others won’t. Consult your request client’s documentation to see if they forward network error messages.