You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 00:24:17