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

如何用Jest动态Mock axios create实现多测试用例?

解决Jest动态Mock Axios时出现的"Cannot read properties of undefined (reading 'then')"错误

错误原因

你的动态Mock逻辑存在两个核心问题:

  1. Mock返回值不符合Axios真实行为:真实的Axios实例调用后会返回一个Promise,但你当前的Mock直接返回了普通数据对象,导致代码中调用.then()或使用await时,因普通对象没有then方法抛出错误。
  2. 模块加载时机错误:使用jest.doMock时,若静态导入useSubscriptionStore,会导致store在Mock生效前就加载了真实的Axios,Mock无法生效。

解决方案1:修正动态Mock并配合动态导入

调整mockAxios函数,让Mock返回Promise,同时在测试用例中动态导入依赖模块:

const mockAxios = (data) => {
  jest.doMock('axios', () => ({
    // 创建的Axios实例调用后返回resolved状态的Promise
    create: jest.fn(() => jest.fn(() => Promise.resolve(data))),
  }));
};

describe('Subscription store', () => {
  beforeEach(() => {
    jest.resetModules();
  });

  it('fetches premium subscription data', async () => {
    // 保持和原接口一致的两层data结构
    const mockResponse = {
      data: {
        data: {
          subscription: [
            { tag: 'premium' },
          ],
        },
      },
    };

    mockAxios(mockResponse);
    // 动态导入store,确保Mock生效后再加载模块
    const { useSubscriptionStore } = await import('./path-to-your-store-file');
    const subscription = useSubscriptionStore();
    
    await subscription.fetch();
    // 添加断言验证结果
    expect(subscription.subscription).toEqual([{ tag: 'premium' }]);
  });
});

解决方案2:更简洁的全局Mock+动态修改返回值

这种写法不需要重置模块和动态导入,适合大多数场景:

// 提前全局Mock axios,返回一个空的mock实例函数
jest.mock('axios', () => ({
  create: jest.fn(() => jest.fn()),
}));

// 提取mock的Axios实例函数,方便后续修改返回值
const mockAxiosInstance = require('axios').create.mockReturnValue();

describe('Subscription store', () => {
  beforeEach(() => {
    // 每个测试用例前重置mock,避免用例间污染
    mockAxiosInstance.mockReset();
  });

  it('fetches free subscription data', async () => {
    // 设置当前用例的返回值
    mockAxiosInstance.mockResolvedValue({
      data: {
        data: {
          subscription: [{ tag: 'free' }],
        },
      },
    });

    const subscription = useSubscriptionStore();
    await subscription.fetch();
    expect(subscription.subscription).toEqual([{ tag: 'free' }]);
  });

  it('fetches premium subscription data', async () => {
    // 设置另一个用例的返回值
    mockAxiosInstance.mockResolvedValue({
      data: {
        data: {
          subscription: [{ tag: 'premium' }],
        },
      },
    });

    const subscription = useSubscriptionStore();
    await subscription.fetch();
    expect(subscription.subscription).toEqual([{ tag: 'premium' }]);
  });
});

内容的提问来源于stack exchange,提问作者Dr. Junior

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 13:57:46