When building modern web applications, it’s essential to ensure that your components interact effectively with APIs to retrieve data and handle potential errors gracefully. At this point, testing is essential process while developing any application, and react is not a exception.
When developing React applications that interact with APIs, one of the common challenges in testing involves mocking API calls to simulate responses, errors and handle various scenarios.
This article explores the integration of Jest and Axios for mocking API calls in a React application, focusing on how to test API’s responses and errors effectively.
Introduction to Jest and Axios
Jest is a popular JavaScript testing framework maintained by Facebook. It provides an intuitive and powerful testing environment, including features like test runners, assertions, and mocking capabilities.On the other hand, Axios is a widely used promise-based HTTP client for making requests in JavaScript, which is very popular in React applications for fetching data from APIs.
Why Mocking Axios?
When writing tests for components that rely on network requests, it’s essential to mock those requests to isolate the component’s behavior from external services.
Mocking Axios requests helps to:
- Isolate Unit Tests: Mocking allows you to focus solely on the component’s logic without worrying about actual network requests or external APIs.
- Control Test Scenarios: You can simulate various scenarios, such as successful responses, error responses, and network failures, to ensure your component handles these cases correctly.
- Improve Test Performance: Mocking eliminates the need for real network requests during testing, making your tests faster and more predictable.
Setting Up the React Project
Before diving into mocking Axios calls, let’s set up a simple React application for demonstration purposes. Make sure you have Nodejs and npm installed on your machine. You do not worry about the jest library, because it comes pre-installed in application built with create-react-app
command.
npx create-react-app jest-axios-mocking
cd jest-axios-mocking
Install Axios:
npm i axios
Now, you can create a new component that fetches data using Axios. For example, let’s create a component that retrieves user data from an API.
// src/UserComponent.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const UserComponent = () => {
const [userData, setUserData] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
axios.get('https://jsonplaceholder.typicode.com/users/1')
.then(response => setUserData(response.data))
.catch(err => setError(err));
}, []);
if (error) {
return <div>Error: {error.message}</div>;
}
if (!userData) {
return <div>Loading...</div>;
}
return (
<div>
<h2>User Data</h2>
<p>Name: {userData.name}</p>
<p>Email: {userData.email}</p>
</div>
);
};
export default UserComponent;
Then, Include the UserComponent
in the src/App.js
file to render users in the page.
// src/App.js
import React from 'react';
import UserComponent from './UserComponent';
function App() {
return (
<div className="App">
<UserComponent />
</div>
);
}
export default App;
Thus, you have a component making Axios requests, the next step is mocking Axios calls with Jest.
Mocking Axios Calls with Jest in React
Now, let’s explore how to mock Axios calls using Jest and simulate API response and errors. First, create a test file for the UserComponent
component named UserComponent.test.js
Mocking Successful API Response
In the first test case, we use axios.get.mockResolvedValue
to simulate a successful API response. The test verifies that the UserComponent
displays the user data as expected.
// src/UserComponent.test.js
import React from 'react';
import { render, waitFor, screen } from '@testing-library/react';
import axios from 'axios';
import UserComponent from './UserComponent';
jest.mock('axios');
describe('UserComponent', () => {
it('should display user data on successful API response', async () => {
const userData = { name: 'John Doe', email: 'john@example.com' };
axios.get.mockResolvedValue({ data: userData });
render(<UserComponent />);
await waitFor(() => screen.getByText('User Data'));
expect(screen.getByText(`Name: ${userData.name}`)).toBeInTheDocument();
expect(screen.getByText(`Email: ${userData.email}`)).toBeInTheDocument();
});
// Add more test cases as needed
});
In this example,
jest.mock('axios')
is used to mock the behavior of the axios library.axios.get.mockResolvedValue({ data: userData })
sets up a mock response for the axios GET request, returninguserData
when theget
method is called.render(<UserComponent />)
renders theUserComponent
.waitFor(() => screen.getByText('User Data'))
waits until the component renders the text ‘User Data’ before proceeding to the expectations.expect(screen.getByText(
Name: ${userData.name})).toBeInTheDocument();
checks if the user’s name is correctly displayed in the component.expect(screen.getByText(
Email: ${userData.email})).toBeInTheDocument();
checks if the user’s email is correctly displayed.
Mocking API Errors
In the second test case, we use axios.get.mockRejectedValue
to simulate an API errors, ensuring that the component displays the appropriate error message.
describe('UserComponent', () => {
// ......
// Second test case
it('should display an error message on API error', async () => {
const errorMessage = 'An error occurred';
axios.get.mockRejectedValue({ message: errorMessage });
render(<UserComponent />);
await waitFor(() => {
expect(screen.getByText(errorMessage)).toBeInTheDocument();
});
});
// Add more test cases as needed
});
In this example,
axios.get.mockRejectedValue({ message: errorMessage })
sets up a mock rejection for the axios GET request, simulating an API error with the given error message.- The rendering and waiting steps are similar to the first test case.
expect(screen.getByText(errorMessage)).toBeInTheDocument();
checks if the error message is correctly displayed.
An Alternative Jest Method: mockImplementation
The other alternative to the methods mockResolvedValue
and mockRejectedValue
methods is the mockImplementation
method. This method allows you to create own implementation of the Axios methods. For example, you can implement the first test case as shown below:
jest.mock('axios');
describe('MyComponent', () => {
it('fetches and displays data', async () => {
const mockData = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
];
axios.get.mockImplementation(() => Promise.resolve({ data: mockData }));
const { findByText } = render(<UserComponent />);
await findByText('John');
await findByText('Jane');
});
it('handles fetch error', async () => {
const errorMessage = 'Network Error';
axios.get.mockImplementation(() => Promise.reject(new Error(errorMessage)));
const { findByText } = render(<UserComponent />);
await findByText('Error fetching data');
});
});
- In the first test case, we use
axios.get.mockImplementation
to replace the real Axios behavior with a custom implementation that returns a resolved promise containingmockData
. - In the second test case, we use
axios.get.mockImplementation
to replace the real Axios behavior with a custom implementation that returns a rejected promise with an error message.
This approach allows you to directly manage the behavior of Axios within your tests using mockImplementation
, as opposed to solely controlling the returned values. Just ensure that the axios.get.mockImplementation
calls are set up appropriately for the scenarios you want to test.
Conclusion
Jest Axios mocking is a valuable technique for testing API interactions in your React applications. It allows you to create controlled test scenarios, ensuring your components behave correctly under various conditions, including successful API responses and error handling.
In this article, we explored how to effectively mock Axios calls in a React application using Jest, with a focus on testing both successful responses and response errors.
If you want to learn more about testing, please check the following articles:
- Test Your React Apps With Jest and Testing Library
- Jest Tutorial: Testing In JavaScript
- Best Testing Libraries for React
- Software Testing For Beginners
Thank you for reading.