How do I test axios in Jest?

I have this action in React:

export function fetchPosts() { const request = axios.get(`${WORDPRESS_URL}`); return { type: FETCH_POSTS, payload: request } } 

How do I test Axios in this case?

Jest has this use case on their site for asynchronous code where they use a mock function, but can I do this with Axios?

Reference: An Async Example

I have done this so far to test that it is returning the correct type:

it('should dispatch actions with the correct type', () => { store.dispatch(fetchPosts()); let action = store.getActions(); expect(action[0].type).toBe(FETCH_POSTS); }); 

How can I pass in mock data and test that it returns?

1

6 Answers

Without using any other libraries:

import * as axios from "axios"; // Mock out all top level functions, such as get, put, delete and post: jest.mock("axios"); // ... test("good response", () => { axios.get.mockImplementation(() => Promise.resolve({ data: {...} })); // ... }); test("bad response", () => { axios.get.mockImplementation(() => Promise.reject({ ... })); // ... }); 

It is possible to specify the response code:

axios.get.mockImplementation(() => Promise.resolve({ status: 200, data: {...} })); 

It is possible to change the mock based on the parameters:

axios.get.mockImplementation((url) => { if (url === ') { return Promise.resolve({ data: {...} }); } else { //... } }); 

Jest v23 introduced some syntactic sugar for mocking Promises:

axios.get.mockImplementation(() => Promise.resolve({ data: {...} })); 

It can be simplified to

axios.get.mockResolvedValue({ data: {...} }); 

There is also an equivalent for rejected promises: mockRejectedValue.

Further Reading:

3

I used axios-mock-adapter. In this case the service is described in ./chatbot. In the mock adapter you specify what to return when the API endpoint is consumed.

import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; import chatbot from './chatbot'; describe('Chatbot', () => { it('returns data when sendMessage is called', done => { var mock = new MockAdapter(axios); const data = { response: true }; mock.onGet(').reply(200, data); chatbot.sendMessage(0, 'any').then(response => { expect(response).toEqual(data); done(); }); }); }); 

You can see it the whole example here:

Service:

Test:

2

I could do that following the steps:

  1. Create a folder __mocks__/ (as pointed by @Januartha comment)
  2. Implement an axios.js mock file
  3. Use my implemented module on test

The mock will happen automatically

Example of the mock module:

module.exports = { get: jest.fn((url) => { if (url === '/something') { return Promise.resolve({ data: 'data' }); } }), post: jest.fn((url) => { if (url === '/something') { return Promise.resolve({ data: 'data' }); } if (url === '/something2') { return Promise.resolve({ data: 'data2' }); } }), create: jest.fn(function () { return this; }) }; 
4

I've done this with nock, like so:

import nock from 'nock' import axios from 'axios' import httpAdapter from 'axios/lib/adapters/http' axios.defaults.adapter = httpAdapter describe('foo', () => { it('bar', () => { nock(') .get('/example') .reply(200, 'some payload') // test... }) }) 
2

Look at this

  1. The function to test album.js
const fetchAlbum = function () { return axios .get("") .then((response) => { return response.data; }); }; 
  1. The test album.test.js
const axios = require("axios"); const { fetchAlbum } = require("../utils.js"); jest.mock("axios"); test("mock axios get function", async () => { expect.assertions(1); const album = { userId: 1, id: 2, title: "sunt qui excepturi placeat culpa", }; const payload = { data: album }; // Now mock axios get method axios.get = jest.fn().mockResolvedValue(payload); await expect(fetchAlbum()).resolves.toEqual(album); }); 
0

For those looking to use axios-mock-adapter in place of the mockfetch example in the Redux documentation for async testing, I successfully used the following:

File actions.test.js:

describe('SignInUser', () => { var history = { push: function(str) { expect(str).toEqual('/feed'); } } it('Dispatches authorization', () => { let mock = new MockAdapter(axios); mock.onPost(`${ROOT_URL}/auth/signin`, { email: '', password: 'test' }).reply(200, {token: 'testToken' }); const expectedActions = [ { type: types.AUTH_USER } ]; const store = mockStore({ auth: [] }); return store.dispatch(actions.signInUser({ email: '', password: 'test', }, history)).then(() => { expect(store.getActions()).toEqual(expectedActions); }); }); 

In order to test a successful case for signInUser in file actions/index.js:

export const signInUser = ({ email, password }, history) => async dispatch => { const res = await axios.post(`${ROOT_URL}/auth/signin`, { email, password }) .catch(({ response: { data } }) => { ... }); if (res) { dispatch({ type: AUTH_USER }); // Test verified this localStorage.setItem('token', res.data.token); // Test mocked this history.push('/feed'); // Test mocked this } } 

Given that this is being done with jest, the localstorage call had to be mocked. This was in file src/setupTests.js:

const localStorageMock = { removeItem: jest.fn(), getItem: jest.fn(), setItem: jest.fn(), clear: jest.fn() }; global.localStorage = localStorageMock; 
2

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like