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

Jest中测试异步函数抛出异常:rejects 的正确用法解析

花韻仙語
发布: 2025-09-15 09:44:51
原创
816人浏览过

Jest中测试异步函数抛出异常:rejects 的正确用法解析

本文深入探讨了在Jest中测试预期抛出异常的异步函数的正确方法。我们将比较两种常见的测试模式,并明确指出 await expect(asyncFun()).rejects.toThrowError() 是推荐且符合Jest rejects 匹配器设计初衷的用法。文章将解释 rejects 期望接收一个 Promise 对象而非函数,以帮助开发者避免测试中的常见误区。

异步函数异常测试的挑战

在现代javascript应用中,异步操作无处不在。当这些异步操作在执行过程中抛出异常时,我们需要一种可靠的方式来测试这些异常是否按预期被捕获和处理。jest作为流行的javascript测试框架,提供了强大的工具来处理这类场景。然而,对于异步函数抛出异常的测试,开发者有时会混淆其正确的使用方式。

两种测试模式的对比

在Jest中测试一个预期会拒绝(即抛出异常)的异步函数时,我们可能会遇到以下两种常见的代码模式:

模式一:直接调用异步函数并传入其返回的 Promise

// 假设 asyncFun 是一个返回 Promise 的异步函数
await expect(asyncFun()).rejects.toThrowError(errorObj);
登录后复制

模式二:将异步函数的调用包裹在一个新的异步函数中

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

那么,这两种模式是否存在差异,哪一种是推荐的用法呢?答案是肯定的,它们之间存在显著差异,并且模式一才是Jest官方文档推荐且设计意图所在的用法。

rejects 匹配器的核心原理

理解这两种模式差异的关键在于深入理解Jest的 rejects 匹配器的工作原理。

Jest的 rejects 匹配器专门用于测试 Promise 是否被拒绝。它的设计初衷是接收一个 Promise 对象作为 expect() 的参数。当 expect() 接收到一个 Promise 时,rejects 会等待该 Promise 的状态变为拒绝(rejected),然后将拒绝的原因与后续的匹配器(如 toThrowError)进行比较。

绘ai
绘ai

ai绘图提示词免费分享

绘ai 153
查看详情 绘ai

与同步 toThrow() 的对比: 为了更好地理解 rejects,我们可以将其与同步的 toThrow() 匹配器进行对比。toThrow() 匹配器用于测试同步函数是否抛出异常。它的用法是 expect(() => { /* 同步函数调用 */ }).toThrowError(errorObj)。在这里,expect() 接收的是一个函数,Jest会执行这个函数,并捕获它可能抛出的同步异常。

模式二的问题所在: 模式二 await expect(async () => { await asyncFun() }).rejects.toThrowError(errorObj) 的问题在于,它将一个函数(async () => { await asyncFun() })传递给了 expect(),而不是一个 Promise。尽管在某些Jest版本或特定场景下,这种写法可能“看起来”能工作,但它并非 rejects 匹配器的设计意图。rejects 期望直接操作一个 Promise,而不是去执行一个函数来获取 Promise。这种不符合设计意图的用法可能导致:

  1. 行为不一致性: 在不同Jest版本或配置下,其行为可能不一致或不可预测。
  2. 可读性降低: 引入了不必要的函数包装,使代码更复杂。
  3. 与文档不符: 偏离了Jest官方文档推荐的最佳实践。

正确实践与示例代码

基于上述分析,测试异步函数抛出异常的正确且推荐的方式是模式一:直接将异步函数调用后返回的 Promise 传递给 expect()。

示例代码:

// 假设我们有一个异步函数,它在某些条件下会抛出错误
async function fetchData(shouldFail) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (shouldFail) {
        reject(new Error('数据加载失败!'));
      } else {
        resolve('数据加载成功!');
      }
    }, 100);
  });
}

// 异步函数示例,使用 async/await 语法
async function processData(input) {
  if (input === 'error') {
    throw new Error('无效的输入');
  }
  return `处理结果: ${input}`;
}

describe('异步函数异常测试', () => {

  test('fetchData 函数应在失败时拒绝并抛出特定错误', async () => {
    // 正确用法:直接调用 fetchData(),它返回一个 Promise
    await expect(fetchData(true)).rejects.toThrowError('数据加载失败!');
    await expect(fetchData(true)).rejects.toThrowError(Error); // 也可以检查错误类型
  });

  test('processData 函数应在输入错误时抛出异常', async () => {
    // 正确用法:直接调用 processData(),它返回一个 Promise
    await expect(processData('error')).rejects.toThrowError('无效的输入');
    await expect(processData('error')).rejects.toThrowError(new Error('无效的输入'));
  });

  // 错误用法示例(不推荐)
  test('不推荐的异步异常测试模式', async () => {
    // 尽管这个测试可能通过,但它不是 Jest rejects 匹配器的设计意图
    // await expect(async () => {
    //   await fetchData(true);
    // }).rejects.toThrowError('数据加载失败!');
    //
    // await expect(async () => {
    //   await processData('error');
    // }).rejects.toThrowError('无效的输入');
  });

  test('fetchData 函数在成功时应解决', async () => {
    await expect(fetchData(false)).resolves.toBe('数据加载成功!');
  });
});
登录后复制

在上面的示例中,await expect(fetchData(true)) 和 await expect(processData('error')) 是正确的用法。fetchData(true) 和 processData('error') 会立即被调用并返回一个 Promise,然后这个 Promise 被传递给 expect(),rejects 匹配器会等待它被拒绝。

注意事项与最佳实践

  • 理解匹配器设计: 始终查阅Jest官方文档,理解每个匹配器的设计意图和期望的输入类型。
  • Promise vs. Function: 区分 rejects(用于 Promise)和 toThrow(用于同步函数)的用法。
  • 立即执行: 当使用 rejects 时,确保你的异步函数被立即调用,以便 expect() 接收到的是一个 Promise 对象,而不是一个未执行的函数。
  • 错误类型和消息: toThrowError 可以接收字符串(匹配错误消息)、正则表达式(匹配错误消息模式)、错误类(匹配错误类型)或错误实例(匹配错误实例和消息)。选择最能表达你测试意图的方式。

总结

在Jest中测试异步函数抛出的异常时,关键在于将异步函数调用后返回的 Promise 对象直接传递给 expect(),并结合 rejects.toThrowError() 匹配器。避免将异步函数调用包裹在另一个函数中传递给 expect(),这虽然可能在某些情况下“奏效”,但并非Jest rejects 匹配器的正确用法,可能导致测试行为的不一致或未来兼容性问题。遵循官方推荐的模式,能够确保测试的健壮性、可读性,并与Jest的设计哲学保持一致。

以上就是Jest中测试异步函数抛出异常: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号