Vue3使用Vitest Mock Axios时出现Cannot read 'then'错误求助
解决Vitest中Mock Axios后出现「TypeError: Cannot read properties of undefined (reading 'then')」的问题
问题场景
在Vue组件Races.vue中实现了getRaces函数,前端运行正常,但使用Vitest编写测试并添加vi.mock模拟axios后,触发测试时抛出错误:TypeError: Cannot read properties of undefined (reading 'then')。
相关代码:
前端组件代码(Races.vue)
getRaces: function () { axios.get(URL) .then(response => { console.log(response) }) .catch(error => { console.log(error); this.errored = true; }) .finally(() => { this.loading = false; }) }
初始测试代码
import { describe, it, expect, beforeEach, vi } from 'vitest' import { shallowMount, flushPromises } from '@vue/test-utils' import Races from '../Races.vue' import axios from 'axios' vi.mock("axios", () => { return { default: { get: vi.fn(), }, }; });
原因分析
当前mock的axios.get是一个空的vi.fn(),默认调用后返回undefined,但真实的axios.get会返回Promise对象。组件代码中调用axios.get().then(...)时,因为undefined没有then方法,所以抛出该错误。
解决方案
需要让mock的axios.get返回Promise对象,根据测试场景选择返回resolved或rejected状态的Promise。
方案1:在mock时直接设置默认返回值
修改vi.mock的返回配置,让get方法返回一个resolved的Promise:
vi.mock("axios", () => { return { default: { // 模拟成功响应,匹配真实axios的响应结构(包含data字段) get: vi.fn().mockResolvedValue({ data: [{ id: 1, name: 'Race 1' }] }), }, }; });
方案2:在测试用例/钩子中动态设置返回值
如果需要在不同测试用例中模拟不同的响应(成功/失败),可以在beforeEach或单个测试用例中设置:
describe('Races组件测试', () => { beforeEach(() => { // 重置mock状态,避免用例间污染 axios.get.mockReset(); }); it('成功获取赛事数据', async () => { // 模拟成功响应 axios.get.mockResolvedValue({ data: [{ id: 1, name: 'Race 1' }] }); const wrapper = shallowMount(Races); wrapper.vm.getRaces(); await flushPromises(); // 等待异步操作执行完成 expect(wrapper.vm.loading).toBe(false); expect(axios.get).toHaveBeenCalled(); }); it('请求失败时设置errored状态', async () => { // 模拟失败响应 axios.get.mockRejectedValue(new Error('请求超时')); const wrapper = shallowMount(Races); wrapper.vm.getRaces(); await flushPromises(); expect(wrapper.vm.errored).toBe(true); expect(wrapper.vm.loading).toBe(false); }); });
关键注意点
- 模拟的响应结构尽量贴近真实axios的返回格式(包含
data字段),避免组件处理响应时出现其他错误。 - 使用
flushPromises()等待异步操作完成,确保断言在Promise执行后触发。 - 测试前用
mockReset()重置mock状态,防止不同测试用例的mock返回值互相干扰。
内容的提问来源于stack exchange,提问作者vera
相关产品推荐
相关产品推荐

