javascript - 在 Vue 应用程序中模拟 axios 以进行前端测试
问题描述
在测试我的 Vue 应用程序的前端时,我有时想跳过与 API 后端的通信。
我想出了以下想法:
- 在 Vuex 商店中添加状态:
skipServerCommunication
. - when
skipServerCommunication = false
:按预期发送 axios 请求 - when
skipServerCommunication = true
:返回模拟数据
axios.post(...)
简单的方法是在每次调用or之前添加一个检查axios.get(...)
,但我不想在我编写的每个 api 函数中添加代码。所以我考虑过使用interceptors
axios 的,但我认为不可能停止请求,只返回模拟数据,对吧?
然后我考虑包装 axios,并动态返回真实的 axios 实例或模拟的 axios 实例,它还实现了基于 Store 状态的所有其他 axios 函数.post()
。.get()
我想过这样的事情(我正在使用 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 无法再提供自动补全功能,因为返回的实例要么是 type
AxiosStatic
要么"MyMockType"
. 所以我考虑实现AxiosStatic
接口,但由于接口中有两个匿名函数,我很难正确地做到这一点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 = 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)
})
})
推荐阅读
- python - 运行 jupyter 会产生“ModuleNotFoundError: No module named 'six'”
- php - 主页帮助 laravel
- c# - 无法访问静态变量
- ffmpeg - 暂停 ffmpeg 流
- objective-c - 为什么@objc 会生成保留和释放调用?
- sql - 显示今天的日期和月份的名称,以小写形式显示 4 个月后的月份(即今天的日期 + 4 个月)
- elasticsearch - do we need to create index specifically in elasticsearch?
- r - 如果 R 中的语句给出了奇怪的结果
- python - 熊猫,查找和删除行
- xml - 如何在 xsl:for-each 中使用 concat() 和 position() 构建 XPath