'Mock axios in a Vue application for frontend testing
When testing the frontend of my Vue application, I sometimes want to skip the communication with the API backend.
I came up with the following idea:
- add state in Vuex store:
skipServerCommunication. - when
skipServerCommunication = false: send the axios request as expected - when
skipServerCommunication = true: return mocked data
The easy way would be to add an check before every call of axios.post(...) or axios.get(...), but I don't want to have to add code in every api function I wrote.
So I thought about using the interceptors of axios, but I think it's not possible to stop a request, and just return mocked data, right?
I then thought about wrapping axios, and dynamically returning the real axios instance or a mocked one, which also implements the .post(), .get() and all the other axios functions based on the Store state. I thought about something like this (I'm working with TypeScript):
import store from '@/vuex-store'
const axios = Axios.create( // real store config );
const axiosMock = {
get(path: string) {
if (path == '/test') {
return Promise.resolve( // mocked data );
}
return Promise.resolve(true)
}
}
class AxiosWrapper {
get instance() {
if (store.state.skipServerCommunication) {
return axiosMock;
}
return axios
}
}
export default new AxiosWrapper();
But this solution has some problems:
- I need to replace all axios calls with
axiosWrapper.instance.get(...). Can I somehow avoid this and mock axios in a way that I can still work withaxios.get(...)? - VSCode isn't able to provide autocompletion anymore because the returned instance is either of type
AxiosStaticor"MyMockType". So I thought about implementing theAxiosStaticinterface, but I struggle to do that correctly because of the two anonymous functions in theAxiosInstanceinterface. Is there an alternative way to overcome this problem?
Solution 1:[1]
Use axios-mock-adapter instead. You can mock axios calls as needed per test, using advanced matching patterns.
Example usage:
import axios from 'axios'
import MockAdapter from 'axios-mock-adapter'
describe('UserList', () => {
it('gets users on mount', async () => {
const mock = new MockAdapter(axios)
mock.onGet('/users').reply(200, {
users: [{ id: 1, name: 'John Smith' }],
})
const wrapper = shallowMount(UserList)
await wrapper.find('.getUsersBtn').trigger('click')
expect(wrapper.vm.users[0].id).toBe(1)
})
})
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Myk Willis |
