Mock axios with Jest and React Testing Library in Typescript (React)

Anish
3 min readApr 12, 2021
Mock Axios with Jest and React Testing Library in Typescript (React)

Have you been using Typescript in your React project lately ? Jest and React Testing Library are your go to tool for writing tests ? And you are having issues trying to test an async method that fetches data from an api using axois ?

Is that a YES ?

Then my friend, you are in right place. I hope this will solve the problem you are facing and you can get that break you’ve been meaning to take.

Let’s get started 👨🏻‍💻

Scenario

We’re going to write a method that uses Axios to make an HTTP Get request from free JSONPlaceholder api.

If you go to https://jsonplaceholder.typicode.com/todos it will give you a list of todos in the following format:

[
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
},
{
"userId": 1,
"id": 2,
"title": "quis ut nam facilis et officia qui",
"completed": false
}
]

Inside your ‘src’ folder of the project, create a ‘types’ folder and add ‘index.ts’ file

├── src
│ ├── types
│ │ ├── index.ts

Since we are working with Todo, let’s create a Todo type first.

Todo

// src/types/index.tsexport type Todo = {
userId: number;
id: number;
title: string;
completed: boolean;
}
Nice and easy right ?

Now, let’s add the async method that fetches the data from the api. I like to seperate my api methods and keep it under ‘api’ folder like this:

├── src
│ ├── api
│ │ ├── index.spec.ts
│ │ ├── index.ts

Inside ‘index.ts’, add the following code that fetches your todos

// src/api/index.ts
export const getTodos = async (): Promise<Todo[]> => {
try {
const url = 'https://jsonplaceholder.typicode.com/todos';
const resp = await axios.get(url);
if (resp.status !== 200) {
throw new Error('Something went wrong');
}
const data: Todo[] = await resp.data;
return data;
} catch (err) {
throw err;
}
};

Here’s the fun part now. Let’s write a test for this getTodos() method.

Inside index.spec.ts, add the following code. I’ve added comments in the code to explain what is happening.

// src/api/index.spec.ts
import axios, { AxiosResponse } from 'axios';
import { getTodos } from '.';
//jest.mock(...) is used to automatically mock the axios module.jest.mock('axios');// Create an object of type of mocked Axios.
const mockedAxios = axios as jest.Mocked<typeof axios>;
describe('getTodos()', () => {
test('should return todo list', async () => {
//Our desired output
const todos: Todo[] = [
{
userId: 1,
id: 1,
title: 'todo-test-1',
completed: false,
},
{
userId: 2,
id: 2,
title: 'todo-test-2',
completed: true,
},
];

//Prepare the response we want to get from axios
const mockedResponse: AxiosResponse = {
data: todos,
status: 200,
statusText: 'OK',
headers: {},
config: {},
};
// Make the mock return the custom axios response
mockedAxios.get.mockResolvedValueOnce(mockedResponse);
expect(axios.get).not.toHaveBeenCalled();
const data = await getTodos();
expect(axios.get).toHaveBeenCalled();
expect(data).toEqual(todos);
});
});

Now, run the test.

PASS  src/api/index.spec.ts
getTodos()
✓ should return todo list (3 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.844 s

It passed 🎉🎉🎉 !!!

You have successfully mocked axios in typescript 💃

Wohoooo 👏👏👏

--

--

Anish

Senior Software Engineer | Mentor | Musician