MSW unit testing API in success & error scenario

2.6k Views Asked by At

I am using MSW for local development and unit testing.

#API fetch
const { loading, error, data } = useFetch('https://made.up/api/usage')

#handler.js
import { rest } from 'msw'

export const handlers = [
  rest.get('https://made.up/api/usage', (req, res, ctx) => {
    return res(
      ctx.status(301),
      ctx.json({
        id: 1,
        firstName: 'John',
      }),
    )
  }),
]

#server.js
import { setupServer } from 'msw/node'
import { handlers } from './handlers'

export const server = setupServer(...handlers)
#setupTests.js
beforeAll(() => {
    server.listen({
      onUnhandledRequest: 'warn',
    })
  })

  afterEach(() => {
    server.resetHandlers()
  })

  afterAll(() => {
    server.close()
  })
#App.test.js
import React from "react";
import { rest } from "msw";
import { render, screen } from "@testing-library/react";
import { server } from "../src/mocks/server";

import App from "../src/App";

test("passes", async () => {
  render(<App />);

  expect(
    // Expect the mocked response to be present in the DOM.
    await screen.findByText(`{"id":1,"firstName":"John"}`)
  ).toBeInTheDocument();
});

test("error", async () => {
  server.use(
    rest.get("https://made.up/api/usage", (req, res, ctx) => {
      return res(
        ctx.status(500),
        ctx.json({
          error: "error"
        })
      );
    })
  );
  render(<App />);

  expect(
    // Expect the mocked error response to be present in the DOM.
    await screen.findByText("Error: error}")
  ).toBeInTheDocument();
});

I am overriding the API handler to test the error scenario. Both the tests do not pass when run together. If I run them individually, they work fine.

Am I missing any step? or we can test the same API for different responses in some other way using MSW?

1

There are 1 best solutions below

0
On

I have got a fix for this issue.

server.use(
    rest.get("https://made.up/api/usage", (req, res, ctx) => {
      return res(
        ctx.status(500),
        ctx.json({
          error: "error"
        })
      );
    })
  );

The above code is permanently overriding the API handler. If we want to override one-time, the

server.use(
    rest.get("https://made.up/api/usage", (req, res, ctx) => {
      return res.once(
        ctx.status(500),
        ctx.json({
          error: "error"
        })
      );
    })
  );

Due to this reason, my tests were not running together but working fine when run individually.