0

0

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

霞舞

霞舞

发布时间:2025-09-15 13:29:01

|

223人浏览过

|

来源于php中文网

原创

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。

元典智库
元典智库

元典智库:智能开放的法律搜索引擎

下载

错误示例:

// 假设 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最佳实践的一致性。遵循这一原则,你的异步错误测试将更加健壮和可靠。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

228

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

297

2023.10.25

promise的用法
promise的用法

“promise” 是一种用于处理异步操作的编程概念,它可以用来表示一个异步操作的最终结果。Promise 对象有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。Promise的用法主要包括构造函数、实例方法(then、catch、finally)和状态转换。

306

2023.10.12

html文本框类型介绍
html文本框类型介绍

html文本框类型有单行文本框、密码文本框、数字文本框、日期文本框、时间文本框、文件上传文本框、多行文本框等等。详细介绍:1、单行文本框是最常见的文本框类型,用于接受单行文本输入,用户可以在文本框中输入任意文本,例如用户名、密码、电子邮件地址等;2、密码文本框用于接受密码输入,用户在输入密码时,文本框中的内容会被隐藏,以保护用户的隐私;3、数字文本框等等。

406

2023.10.12

2026赚钱平台入口大全
2026赚钱平台入口大全

2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

32

2026.01.31

高干文在线阅读网站大全
高干文在线阅读网站大全

汇集热门1v1高干文免费阅读资源,涵盖都市言情、京味大院、军旅高干等经典题材,情节紧凑、人物鲜明。阅读专题下面的文章了解更多详细内容。

23

2026.01.31

无需付费的漫画app大全
无需付费的漫画app大全

想找真正免费又无套路的漫画App?本合集精选多款永久免费、资源丰富、无广告干扰的优质漫画应用,涵盖国漫、日漫、韩漫及经典老番,满足各类阅读需求。阅读专题下面的文章了解更多详细内容。

28

2026.01.31

漫画免费在线观看地址大全
漫画免费在线观看地址大全

想找免费又资源丰富的漫画网站?本合集精选2025-2026年热门平台,涵盖国漫、日漫、韩漫等多类型作品,支持高清流畅阅读与离线缓存。阅读专题下面的文章了解更多详细内容。

6

2026.01.31

漫画防走失登陆入口大全
漫画防走失登陆入口大全

2026最新漫画防走失登录入口合集,汇总多个稳定可用网址,助你畅享高清无广告漫画阅读体验。阅读专题下面的文章了解更多详细内容。

9

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.4万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.6万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

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