VueJS中使用Jest模拟axios GET请求时出现getPost导入报错
Vue项目Jest测试getPost方法的报错成因与修复
触发TypeError: (0 , _Post.getPost) is not a function的核心成因
- 对方法的导出属性存在本质误解:你定义的
getPost是Vue组件选项上的实例方法,既没有通过export做模块级具名导出,也不属于组件对外暴露的可独立调用的函数,直接用import { getPost } from '@/views/Post.vue'永远无法拿到该方法,这是报错的直接来源。 - 调用上下文完全缺失:即便能拿到方法,方法内部依赖
this指向的组件实例资源,包括this.refreshToken()、this.$cookie接口、组件引入的http封装实例、this.post状态字段,脱离组件实例直接调用会触发连续的空引用错误。 - 测试逻辑与业务实现不匹配:
- 原
getPost方法没有显式设置返回值,测试中await getPost()拿到的返回结果为undefined,不存在返回空Map、返回mock列表的逻辑分支。 - 代码中实际发起请求的是项目封装的
http实例,并非全局直接引入的原生axios,对全局axios做mock根本无法拦截组件发出的请求。 - 测试中断言的调用参数不完整,实际请求携带了自定义鉴权头、Content-Type配置,仅断言路径参数无法匹配实际调用结构。
- 方法本身不接收入参,调用时传入的
['1']参数不会被方法读取,帖子ID的来源是$cookie存储的postid值。
- 原
对应修复方案
- 调整测试的对象获取路径
不直接导入组件内部方法,通过@vue/test-utils挂载组件获取实例后再调用实例方法,同时对组件依赖的封装http模块做mock:import { mount } from '@vue/test-utils' import Post from '@/views/Post.vue' // mock组件内部引入的封装http实例 jest.mock('@/utils/http', () => ({ get: jest.fn() })) import http from '@/utils/http' - 补齐组件实例的依赖打桩
挂载组件时注入$cookie接口的模拟实现,同时对refreshToken方法打桩,保证方法执行时的上下文可用:const wrapper = mount(Post, { mocks: { $cookie: { get: (key) => { if (key === 'postid') return '123' if (key === 'token') return 'test-token' } } }, methods: { refreshToken: jest.fn() } }) const vm = wrapper.vm - 修正测试断言逻辑
替换mock目标为封装后的http.get方法,按照业务逻辑调整断言方向:原方法没有返回值,执行成功后会将响应数据赋值给vm.post,执行失败时会打印error.response,同时断言完整的请求参数结构。
参考用例:it('请求成功时正确将响应赋值给post属性', async () => { const mockPostData = { id: 123, title: '测试帖子' } http.get.mockResolvedValue({ data: mockPostData }) await vm.getPost() // 断言请求参数与业务逻辑一致 expect(http.get).toHaveBeenCalledWith( '/posts/123', expect.objectContaining({ headers: { Authorization: 'Bearer test-token', 'Content-type': 'application/json' } }) ) // 断言状态赋值正确 expect(vm.post).toEqual(mockPostData) }) it('请求失败时正确打印错误响应', async () => { const mockError = { response: { status: 404, msg: '帖子不存在' } } http.get.mockRejectedValue(mockError) const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {}) await vm.getPost() expect(logSpy).toHaveBeenCalledWith(mockError.response) logSpy.mockRestore() })
内容的提问来源于stack exchange,提问作者ckyzm
相关产品推荐
相关产品推荐

