How do I test axios in Jest?
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 === 'www.example.com') { 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:
- Jest mocking documentation
- A GitHub discussion that explains about the scope of the
jest.mock("axios")
line. - Another answer of mine which addresses applying the techniques above to Axios request interceptors.
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('https://us-central1-hutoma-backend.cloudfunctions.net/chat').reply(200, data); chatbot.sendMessage(0, 'any').then(response => { expect(response).toEqual(data); done(); }); });});
You can see it the whole example here:
Service:https://github.com/lnolazco/hutoma-test/blob/master/src/services/chatbot.js
Test:https://github.com/lnolazco/hutoma-test/blob/master/src/services/chatbot.test.js
I could do that following the steps:
- Create a folder __mocks__/ (as pointed by @Januartha comment)
- Implement an
axios.js
mock file - 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; })};