如何以编程方式判断函数是否为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
相关产品推荐
相关产品推荐

