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

Sinon Stub触发意外UnhandledPromiseRejectionWarning且测试不通过

解决异步函数测试的UnhandledPromiseRejectionWarning和断言失败问题

咱们先拆解一下你遇到的两个问题,其实它们是相关的,核心原因是异步函数的错误处理和断言方式不对。

为什么会出现UnhandledPromiseRejectionWarning?

当你用sandbox.stub(sqlFileReader, 'read').rejects(...)模拟Promise拒绝时,你的测试代码里如果没有正确捕获这个拒绝,Node.js就会认为这是一个未处理的Promise拒绝,从而抛出警告。你之前用expect(async () => {...}).to.throw()的写法,本质上没有正确处理这个Promise的拒绝状态,导致警告出现。

为什么测试断言失败?

普通的to.throw()断言只能捕捉同步函数抛出的错误,而你的performDatabaseConnectivityHealthCheck是异步函数,它的错误是通过Promise拒绝传递的,不是同步抛出的。所以to.throw()根本捕捉不到这个错误,自然断言失败。

解决方案:使用chai-as-promised处理异步断言

要同时解决这两个问题,我们需要用专门处理Promise的断言工具——chai-as-promised,它能完美处理异步函数的错误断言,同时自动处理Promise拒绝,消除警告。

步骤1:安装并引入chai-as-promised

如果还没安装,先执行:

npm install chai-as-promised --save-dev

然后在你的测试文件顶部添加:

const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');

// 启用chai-as-promised插件
chai.use(chaiAsPromised);

步骤2:修改测试用例的断言逻辑

把原来的同步断言写法改成异步Promise断言:

it('throws a \'Database Healthcheck Error\' error when the Database Healthcheck gives the wrong data', async () => {
  // 用sinon的.rejects()模拟异步函数抛出错误,这是最简洁正确的写法
  sandbox.stub(sqlFileReader, 'read').rejects(new Error("ER_PROCACCESS_DENIED_ERROR: execute command denied to user 'dchambers'@'%' for routine 'uk_txtloan.connection_ids'"));
  
  // 直接断言Promise会被拒绝,并用rejectedWith匹配错误信息
  await expect(RiskAffordabilityReportService.performDatabaseConnectivityHealthCheck(rars.logger))
    .to.be.rejectedWith("ER_PROCACCESS_DENIED_ERROR: execute command denied to user 'dchambers'@'%' for routine 'uk_txtloan.connection_ids'");
});

额外说明:关于sinon stub的写法

你尝试的几种写法里,.rejects(...)是sinon专门为异步函数设计的正确写法,它会自动返回一个被拒绝的Promise,比.returns(Promise.reject(...))更简洁可靠。之前的.throws(...)是用来模拟同步函数抛出错误的,不适合异步场景,所以无效。

这样修改后,测试会正确捕获异步函数的Promise拒绝,既不会出现UnhandledPromiseRejectionWarning,也能让断言通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:16:31