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

如何以编程方式判断函数是否为async?Jasmine it函数猴子补丁场景

解决Jasmine it()函数猴子补丁中判断async函数的问题

嘿,我刚好踩过这个坑!你之前用instanceof Promise判断肯定行不通,因为async函数本身是Function类型,不是Promise实例——只有当你调用这个async函数的时候,它才会返回一个Promise对象。直接拿函数本身去和Promise比,结果自然永远是false啦。

下面给你两种可行的解决方案,根据你的需求选就行:

方案1:直接判断函数是否为AsyncFunction类型

async函数的构造器名称是AsyncFunction,我们可以通过这个特性直接判断:

// 先保存原始的it函数
const originalIt = window.it;

// 重写it函数
window.it = function(testDescription, testFn) {
  // 判断传入的测试函数是不是async函数
  const isAsyncTest = testFn.constructor.name === 'AsyncFunction';

  if (isAsyncTest) {
    console.log(`测试用例 "${testDescription}" 是async函数`);
    // 这里添加你需要的自定义逻辑,比如包装async函数
    return originalIt(testDescription, async () => {
      // 你的前置/后置处理逻辑
      await testFn();
    });
  } else {
    // 非async函数直接调用原始it
    return originalIt(testDescription, testFn);
  }
};

这种方法的优点是在测试函数执行前就能判断,缺点是如果环境对AsyncFunction的支持有差异(不过现代测试环境基本都没问题),可能会有兼容问题。

方案2:判断测试函数的返回值是否为Promise

如果你想覆盖所有返回Promise的情况(包括非async但手动返回Promise的测试函数),可以在调用测试函数后判断它的返回值:

const originalIt = window.it;

window.it = function(testDescription, testFn) {
  return originalIt(testDescription, function() {
    let result;
    try {
      // 执行测试函数,获取返回值
      result = testFn();
    } catch (err) {
      // 处理同步抛出的错误
      throw err;
    }

    // 判断返回值是否为Promise
    if (result instanceof Promise) {
      console.log(`测试用例 "${testDescription}" 返回了Promise`);
      // 这里添加对Promise的自定义处理
      return result.then(() => {
        // 比如添加断言、日志等
      }).catch(err => {
        // 自定义错误处理
        throw err;
      });
    }

    // 非Promise返回值直接返回
    return result;
  });
};

这种方法更通用,不管是async函数还是手动返回Promise的函数都能捕获到,不过需要执行一次测试函数才能判断。

为什么你的原方法不行?

再强调一下:testFn instanceof Promise判断的是testFn这个对象是不是Promise的实例,但testFn是一个函数(Function类型),只有当你调用它testFn()的时候,才会得到一个Promise实例。所以直接判断函数本身肯定永远是false啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 06:53:08