在测试 Vue 应用程序的前端时,我有时想跳过与 API 后端的通信。
我想出了以下想法:
- 在 Vuex 存储中添加状态:
skipServerCommunication
. - 当
skipServerCommunication = false
: 按预期发送axios请求 - 当
skipServerCommunication = true
: 返回模拟数据
最简单的方法是在每次调用 axios.post(...)
之前添加检查或axios.get(...)
,但我不想在我编写的每个 api 函数中添加代码。
所以我考虑使用 interceptors
axios,但我认为不可能停止请求,只返回模拟数据,对吗?
然后我考虑包装 axios,并动态返回真实的 axios 实例或模拟实例,它也实现了 .post()
, .get()
以及所有其他基于 Store 状态的 axios 函数。我想到了这样的事情(我正在使用 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();
但是这个解决方案有一些问题:
- 我需要将所有 axios 调用替换为
axiosWrapper.instance.get(...)
。我可以以某种方式避免这种情况并以我仍然可以使用的方式模拟 axiosaxios.get(...)
? - VSCode 无法再提供自动完成功能,因为返回的实例的类型为
AxiosStatic
或"MyMockType"
。所以我考虑实现AxiosStatic
接口(interface),但由于AxiosInstance
中有两个匿名函数,我很难正确地做到这一点界面。有没有其他方法可以解决这个问题?
最佳答案
使用axios-mock-adapter
反而。您可以根据每个测试的需要,使用高级匹配模式模拟 axios
调用。
用法示例:
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)
})
})
关于javascript - 在 Vue 应用程序中模拟 axios 以进行前端测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64079696/