I’m making a test that includes an axios call to an endpoints. to mock out the call to the endpoint and return some custom data so that I’m not hitting a server everytime I’m testing.
Here is the code for the action that is in it’s own action.js file.
login ({commit}, user) {
return new Promise((resolve, reject) => {
axios.post(‘https://backendauth.free.beeceptor.com/api/login', user)
.then(resp => {
console.log(‘response here’)
console.log(resp)
console.log(resp.data)
const token = resp.data.success.token
const user = resp.data.user
localStorage.setItem(‘token’, token)
axios.defaults.headers.common[“Authorization”] = “Bearer “ + token;
commit(‘LOGIN_SUCCESS’, token, user)
When logging in the action calls out to an endpoint and that endpoint returns a token which is stored in local storage. The token is also appended to the axios default headers so I don’t have to attach the token everytime to make an axios call in the application.
Now to the test. I’ve written a test that sucessfully mocks the axios post however fails with an error when setting the default headers for the mock.
Here is the error
TypeError: Cannot read property ‘headers’ of undefined
37 | const user = resp.data.user
38 | localStorage.setItem(‘token’, token)
\> 39 | axios.defaults.headers.common[“Authorization”] = “Bearer “ + token;
| ^
40 | commit(‘LOGIN_SUCCESS’, token, user)
41 | resolve(resp)
42 | })
Here is the test including the mock
import actions from “../../src/store/actions”;
let url = “”;
let body = “”;
jest.mock(“axios”, () => ({
post: (_url, _body, config) => {
return new Promise((resolve) => {
resolve({‘data’ : {‘success’: {‘token’ : ‘test’}})
})
},
}))
describe(‘login action’, () => {
it(“let the user login and access login success mutator”, async() => {
const commit = jest.fn()
const username = ‘test’
const password = ‘test’
await actions.login({commit}, {username, password})
})
})
The jest mock is a full mock which returns a promise when called, with the data I need, however the code fails when trying to set the headers. Is there a way I can mock this out as well or do I need to write the mock in a different way?
Solution :
Here is how you do it for anyone with the same problem. Npm install axios-mock-adapter and then use the following code but change it for the needs.
import actions from “../../src/store/actions”;
import axios from ‘axios’;
import MockAdapter from ‘axios-mock-adapter’;
describe(‘login action’, () => {
it(“let the user login and access login success mutator”, async() => {
let mockAdapter = new MockAdapter(axios);
mockAdapter.onPost(‘https://hotel-dev.devtropolis.co.uk/api/apilogin').reply(200, {
token: ‘test token’,
user: {username: ‘test’, password: ‘test’}
});
const commit = jest.fn()
const username = ‘test’
const password = ‘test’
await actions.login({commit}, {username, password})
expect(axios.defaults.headers.common.Authorization).toBe(‘Bearer test token’)
expect(commit).toHaveBeenCalledWith(
“LOGIN_SUCCESS”,’test token’, {username, password})
})
})