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

如何在Jest中测试Promise?请求调用断言不符问题求助

Jest测试时axios请求调用次数不符合预期的问题解决

问题根源

  1. mock对象错误:你直接mock了axios.post和axios.get,但业务代码中所有请求都是通过axios.create()创建的实例来调用post/get方法,全局axios的方法mock不会作用于这些实例,导致实例的请求没有被统计到。
  2. 异步流程未完全等待:init函数中Promise.any([getPromise1, getPromise2])没有被await,虽然get()返回了init()的Promise,但init()内部的promises异步链并没有被等待,导致测试在部分异步操作完成前就执行了断言。

修正方案

步骤1:正确mock axios.create

修改测试代码,mockaxios.create使其返回包含mock post/get方法的对象,这样所有通过create创建的实例的请求都会被追踪:

// 先重置所有mock
jest.mock('axios');

// 创建mock的实例方法
const mockAxiosInstance = {
  post: jest.fn().mockResolvedValue({
    status: 200,
    data: { data: '123' }
  }),
  get: jest.fn().mockResolvedValue({
    status: 200,
    data: { id: '123' }
  })
};

// 让axios.create返回这个mock实例
axios.create.mockReturnValue(mockAxiosInstance);

步骤2:确保等待所有异步操作完成

修改业务代码中的init函数,await住Promise.any的结果,这样get()返回的Promise会等待所有相关异步流程完成:

async function init() {
  try {
    const result = await Promise.any([getPromise1, getPromise2]);
    return result;
  } catch (error) {
    return error;
  }
}

修正后的测试断言

现在断言需要针对mock的实例方法,同时保留axios.create的调用次数校验:

await get();

expect(axios.create).toBeCalledTimes(3);
expect(mockAxiosInstance.post).toBeCalledTimes(1); // 对应getToken里的POST请求
expect(mockAxiosInstance.get).toBeCalledTimes(2); // 对应两个GET请求

额外优化建议

避免使用new Promise(async (resolve, reject) => {})这种反模式写法——async函数本身就返回Promise,直接用async函数代替即可,比如把getPromise1改成:

const getPromise1 = async () => {
  const token = await getToken();
  const http = axios.create({
    headers: { Authorization: `Token ${token}` }
  });
  const response = await http.get("/endpoint-2");
  return response.data;
};

这样代码更简洁,也能避免Promise executor中使用async带来的潜在问题。

内容的提问来源于stack exchange,提问作者Denilson Raimundo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 05:46:09