首页 > web前端 > js教程 > 正文

Jest中异步函数异常测试的正确姿势:expect().rejects用法详解

霞舞
发布: 2025-09-15 13:29:01
原创
213人浏览过

Jest中异步函数异常测试的正确姿势:expect().rejects用法详解

在Jest中测试异步函数抛出异常时,理解expect().rejects的正确用法至关重要。本文将详细阐述如何正确使用rejects断言一个Promise被拒绝并抛出特定错误,并指出常见的错误模式:将异步函数包裹在另一个函数中传递给expect,强调rejects旨在直接作用于Promise对象,而非函数。

理解Jest中的异步错误测试

javascript的异步编程中,promise是处理异步操作结果的核心机制。当异步操作失败时,promise会进入拒绝(rejected)状态,并通常伴随一个错误对象。jest提供了.rejects匹配器,专门用于测试promise是否被拒绝,并结合.tothrowerror()来验证拒绝的原因是否是预期的错误。

与同步函数的错误测试不同,同步函数使用expect(() => syncFun()).toThrowError(),需要将可能抛出错误的函数包裹在一个匿名函数中。然而,对于异步函数,.rejects的工作方式有所不同。

expect().rejects 的核心原理

expect().rejects旨在直接作用于一个Promise对象。当expect接收到一个Promise时,它会等待该Promise解析(resolve)或拒绝(reject)。如果Promise被拒绝,rejects链上的匹配器(如.toThrowError())将对拒绝值进行验证。

正确的异步错误测试方式

测试一个预期会抛出错误的异步函数asyncFun()的正确方式是直接将asyncFun()的调用结果(即一个Promise)传递给expect。

示例代码:

// 假设有一个异步函数,它会返回一个被拒绝的Promise
async function asyncFunThatThrows() {
  return new Promise((resolve, reject) => {
    // 模拟异步操作后抛出错误
    setTimeout(() => {
      reject(new Error('Async operation failed!'));
    }, 100);
  });
}

// 或者一个async函数直接抛出错误
async function anotherAsyncFunThatThrows() {
  await new Promise(r => setTimeout(r, 50)); // 模拟一些异步工作
  throw new Error('Another async error!');
}

describe('Testing async functions that throw errors', () => {
  test('should correctly catch an error from a rejected promise', async () => {
    const errorObj = new Error('Async operation failed!');
    // 直接将Promise传递给expect
    await expect(asyncFunThatThrows()).rejects.toThrowError(errorObj);
  });

  test('should correctly catch an error from an async function that throws', async () => {
    const errorObj = new Error('Another async error!');
    // 直接将Promise(async函数的返回值)传递给expect
    await expect(anotherAsyncFunThatThrows()).rejects.toThrowError(errorObj);
  });
});
登录后复制

在这种模式下,asyncFunThatThrows()或anotherAsyncFunThatThrows()被调用后会立即返回一个Promise。await expect(...)会等待这个Promise完成,如果它被拒绝,rejects.toThrowError()就会对拒绝值进行匹配。

常见的误区与原因分析

一个常见的错误是将异步函数再次包裹在一个匿名异步函数中,然后将其传递给expect。

青柚面试
青柚面试

简单好用的日语面试辅助工具

青柚面试 57
查看详情 青柚面试

错误示例:

// 假设 asyncFun() 是一个会返回被拒绝Promise的异步函数
await expect(async () => {
  await asyncFun();
}).rejects.toThrowError(errorObj);
登录后复制

为什么这是错误的或不被推荐的:

  1. expect接收的是函数而非Promise: 在这个例子中,expect接收到的是一个匿名异步函数 async () => { await asyncFun() },而不是asyncFun()返回的Promise。尽管Jest在内部可能对传入的函数进行了某种处理,但这不是rejects设计的初衷和推荐用法。
  2. rejects期望Promise: .rejects匹配器是为Promise设计的。当它接收到一个函数时,其行为可能不符合预期,或者在未来的Jest版本中可能不再支持。Jest的官方文档明确指出.rejects应该用于Promise。
  3. 不必要的复杂性: 将一个异步函数包裹在另一个异步函数中,增加了不必要的嵌套和复杂性,同时也模糊了测试的意图。

这种写法在某些情况下可能“看似有效”,但它不是Jest官方文档推荐或保证的行为。正确的做法是始终将异步函数执行后返回的Promise直接传递给expect。

注意事项

  • await的重要性: 在使用expect().rejects时,必须在expect调用前使用await。这是因为expect().rejects本身返回一个Promise,你需要等待这个Promise解析,以确保断言逻辑能够执行。
  • Promise的拒绝状态: 只有当Promise进入拒绝状态时,.rejects才能捕获到错误。如果异步函数在执行过程中抛出异常,但没有被try...catch捕获并导致Promise拒绝,那么测试可能无法按预期工作。确保你的异步函数在失败时返回一个被拒绝的Promise。

总结

在Jest中测试异步函数抛出异常时,请牢记expect().rejects是为Promise设计的。正确的做法是直接将异步函数调用后返回的Promise传递给expect,例如 await expect(asyncFunctionCall()).rejects.toThrowError(error)。避免将异步函数包裹在另一个匿名函数中传递给expect,以确保测试的准确性、可读性以及与Jest最佳实践的一致性。遵循这一原则,你的异步错误测试将更加健壮和可靠。

以上就是Jest中异步函数异常测试的正确姿势:expect().rejects用法详解的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
热门推荐
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号