Mocking HTTP Request in React using Mock Service Worker

Vidhi Kapadia
Simform Engineering
7 min readDec 28, 2023

Enhance API testing efficiency with React Testing Library and Mock Service Worker

Have you ever found yourself deploying a new feature and feeling concerned about the possibility of introducing new bugs with each update? A minor change in an API could potentially disrupt the Frontend. What if there were a way to identify issues in an existing app simply by running test cases? In this blog post, we will delve into the use of React Testing Library to replicate DOM manipulation and Mock Service Worker (MSW) to mock HTTP requests. If you’re unfamiliar with React Testing Library, please take a moment to check out our introduction to it.

Understanding the need for mocking HTTP requests

Mocking HTTP requests during testing is essential for several compelling reasons:

  1. Speed: Mocking HTTP requests is significantly faster than making actual API calls, improving test execution speed.
  2. Isolation and Stability: Tests are less affected by external factors, ensuring stability.
  3. Data Control: Developers can create specific scenarios for testing, ensuring components can handle specific edge cases.
  4. Consistency: Mocked responses remain constant, reducing the likelihood of test failures due to external API changes.
  5. Cost Reduction: Mocking prevents costs associated with real API calls, particularly when running individual test cases.

Popular mocking libraries used with React

You can choose from many popular mocking libraries options, each offering unique features and advantages:

  1. MSW(Mock Service Worker) is an API mocking library that allows you to write client-agnostic mocks and reuse them everywhere, regardless of tools or frameworks.
  2. Nock is a Node.js library specifically designed for mocking HTTP requests which offers a rich set of features for controlling request behaviour and defining expected responses.
  3. axios-mock-adapter is a lightweight and easy-to-use mocking library specifically designed for Axios.

Among the various API mocking libraries available, MSW stands out as a powerful tool. We’ll explore how to mock API calls and write test cases using MSW to build robust and reliable applications.

Axios or Fetch ? MSW works with both

MSW simplifies your testing process as it’s independent of any specific HTTP library like Axios or Fetch.

Prerequisite

Before we start, ensure these in your development environment:

  1. Install Node.js and npm on your development machine.
  2. Set up a React development environment with Vite.

How to setup Jest and Testing library in a React project with Vite

Since we are using Vite for creating a React application, we will use Vitest package, which is compatible with Vite.

Step 1: Install the necessary dependencies.

npm install -D vitest jsdom @testing-library/react jest jest-environment-jsdom @testing-library/jest-dom

Step 2: After the installation, add test script in the package.json.

Step 3: Create a new file in the root of your project with the name setupTests.js .

Step 4: Next, open the vite.config.js file and add the following code to it.

Note: When we use create-react-app for creating the project, there’s no requirement for a separate installation of Jest since it’s already included.

Creating UI for writing test cases

We will create a simple Todo List App that allows users to fetch a list of existing tasks and add new tasks to it.

Here, we will use the freely available JSON Placeholder API for demonstration and testing purposes.

Inside the components folder, create three files namely TodoWrapper.jsx , Todos.jsx and TodoForm.jsx.

Get the whole code from this repository.

Step 1: Inside the TodoWrapper.jsx component, a get request is made to fetch a list of todos .

Step 2: Inside the Todos.jsx component, we map over the todos props and display them in a list.

If there is no data inside todos props, it will display No todo found .

Step 3: For adding a new todo to a list, write text inside the input textbox and click on the submit button. On clicking the button, it will call post API and the new todo will be added to a list.

Display todos

The most recommended library for mocking when writing tests with the React Testing library is MSW (Mock Service Worker).

MSW setup

Step 1: Install msw library as a dev dependency.

npm install msw --save-dev

Step 2: Create a file server.js inside the mocks folder.

Step 3: Create a file handlers.js for handling the HTTP request.

For our scenarios, we need to mock REST API. Other option available is GRAPHQL API .

Here, we are mocking GET and POST API responses.

  • The first argument is the same URL that we are using to fetch todos.
  • The second argument is the function that returns Mocked JSON Data and it should match the exact response which the component expects.

Testing with MSW

Now we have MSW set with the server and handlers, let’s write our test for TodoWrapper component.

Create a file named TodoWrapper.test.jsx inside the _tests_ folder.

First, let’s ensure that the component renders without any errors and displays the heading correctly.

To run the test in Vite, use the following command.

npm run test
First test case for checking component renders successfully

Now, we need to write a test case to ensure the list of todos is displayed when the component mounts and fetch data from the HTTP request.

We have used findAllByRole method from React testing library as we expect multiple list items to be present in the DOM.

For our assertion, we expect todo’s array to have a length of 3. Now, where did the 3 come from? Well, it’s the length of the mocked array response that we have passed in handlers file.

If we run this test, our test fails. You can see that expected length 3 and received length is 10. This is because we have not told our test to use a mock service worker. It has called the actual API endpoint, which returns an array of 10 todos.

Test fails as it calls actual HTTP endpoint

To tell our test to use MSW, let’s modify the setupTests.js with the code snippet below.

Now, if we run our test, it passes. This ensures MSW is considered when running the tests.

Test passes after adding Jest functions in setupTest file

Let’s also assert against the mocked response that we passed in our MSW server and check if it renders correctly on DOM.

So now you can see the test for fetching todo passed successfully.

Display todo list testcase

Let’s write some more tests

A test case that verifies the TodoForm component correctly handles user input, adds the entered todo to the list, and displays the added todo.

Here, we are using fireEvent from @testing-library/react to simulate user interaction with input elements and Add Todo button.

The user enters the text ideas into the input field using fireEvent.change(). Then, it triggers the Add Todo button's click event using fireEvent.click() .

waitFor() to ensure that the assertion is executed only after the API response has been processed and the list has been updated.

MSW intercepts the API request and returns a mock response with a status code of 201, representing a successful todo creation.

The assertion checks whether the list item containing the text ideas is present in the DOM.

Add todo testcase

MSW error handling

If we take a look at our TodoWrapper’s component, we are setting an error message when the HTTP request fails.

Setting error message

The same error message is displayed on the DOM that there is an error fetching todos.

Displays an error message

Let’s see how to tell MSW to respond with an error status when an HTTP request fails.

So instead of mocking requests in setupTests.js file, we will mock requests for error handling in the test itself.

It is important to note that this handler for the 500 status code applies to this single test. As we are resetting the handlers using afterEach(() => server.resetHandlers()) after each test runs.

Now, as we run the test, we see all the four test cases are running as expected.

Error handling testcase

For the complete source code, check out the GitHub repository.🚀

Conclusion

In this blog, we emphasized the importance of mocking HTTP requests. We explored setting up a testing environment for a React app created using Vite from scratch. Using a basic todo list example, we demonstrated how to mock HTTP requests using Mock Service Worker (MSW).

It’s worth noting that MSW offers a wide range of additional features, so feel free to explore its documentation for more comprehensive insights.

For more updates on the latest development trends, follow the Simform Engineering blog.

Follow Us: Twitter | LinkedIn

--

--