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

如何使用Jest创建可被识别为async函数的mock/spy函数?

问题原因
  • 业务代码中的async函数校验逻辑存在两处缺陷:第一是变量引用错误,函数入参直接定义为consumerFunction,校验时却引用了未定义的args.consumerFunction;第二是判断逻辑不成立,async函数本质是AsyncFunction类型的函数对象,只有执行后才会返回Promise,直接读取函数本身的.then属性永远为undefined,无法正确识别async函数。
  • jest.fn()默认生成的是普通Function类型的mock函数,即便传入async函数作为实现,外层包装的mock函数本身不属于AsyncFunction类型,若通过构造器类型判断是否为async函数,这类mock会被判定为非法。
解决方案

方案1:生成可通过AsyncFunction类型校验的Jest mock(无需修改业务代码)

通过修改mock函数原型链的方式,可以让jest生成的mock函数被识别为原生async函数,同时保留全部jest mock能力,封装方法如下:

const AsyncFunction = (async () => {}).constructor;

const createAsyncMock = (impl) => {
  const mockFn = jest.fn(async (...args) => impl?.(...args));
  Object.setPrototypeOf(mockFn, AsyncFunction.prototype);
  return mockFn;
}

使用时替换原有jest.fn调用即可:

beforeEach(()=> {
  mockAsyncConsumerFunctionSpy = createAsyncMock((recordBody) => `${recordBody} - resolved consumer`);
  logSpy = jest.spyOn(console, 'log').mockImplementation(() => null);
})

生成的mock函数可正常通过函数类型校验、async函数类型校验,同时支持所有jest mock的断言方法与属性访问,完全满足测试需求。

方案2:优化业务校验逻辑(工程实践层面更推荐)

业务逻辑中强制要求入参必须是async声明的函数没有实际价值:await关键字兼容所有返回thenable对象(带.then方法的Promise/类Promise实例)的函数,无论函数是async声明,还是普通函数手动返回Promise,执行效果完全一致。原有强制校验async类型的逻辑兼容性很差,会拦截所有合法的Promise返回函数、测试mock函数。
建议将校验逻辑调整为校验函数执行后的返回值是否为Promise即可,修改后的业务代码如下:

exports.consumeRecords = async (consumerFunction, records) => {
  if (!consumerFunction) {
    throw new Error(`Missing required argument, consumerFunction, in consumeRecords function`)
  }
  if (typeof consumerFunction !== 'function') {
    throw new Error(`Argument, consumerFunction, is not of type 'function' in consumeRecords function.  Type found: ${typeof consumerFunction}`)
  }
  const executeResult = consumerFunction(records);
  if (!executeResult || typeof executeResult.then !== 'function') {
    throw new Error(`Argument, consumerFunction, must return a Promise when called in consumeRecords function.`)
  }
  await executeResult;
  // ... 剩余业务逻辑
}

调整后原有jest.fn(async () => {})写法的普通mock可以直接使用,不需要额外处理,同时业务代码对入参的兼容性也会显著提升。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:15:13