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

为何我的try/catch断言单元测试执行失败

问题说明

现有逻辑:自定义类内部实例化Session类,当MainClass的foo方法抛出异常时,会调用session实例的deleteEmpty方法。
测试需要验证两个核心点:

  • 捕获到的thrown变量为有效值
  • deleteEmpty方法确实被调用
    当前异常现象:仅保留thrown非空的断言时测试可正常通过,新增deleteEmpty被调用的断言后测试直接失败,控制台无任何失败原因输出。

附相关代码

MainClass 代码

const token = "12345";
const data = { /* 业务字段 */ };

const session = new Session(token, data);

async function foo() {
    try {
       // 业务执行逻辑
    } catch(error) {  
       await this.session.deleteEmpty();
       throw error;
    }
}

测试文件代码

const sessionMock = Sinon.createStubInstance(Session)
let thrown: Error | undefined = undefined;

sandbox.stub(MainClass, 'foo').throws();

try {
    await MainClass.foo();
} catch(error) {
    thrown = error;
}

expect(sessionMock.deleteEmpty).calledOnce;
expect(thrown).to.not.be.undefined;

问题根因
  1. 测试中直接stub了整个MainClass.foo方法,相当于完全替换了foo的原有实现,原方法catch块中调用this.session.deleteEmpty()的逻辑根本不会执行,自然不可能触发deleteEmpty的调用。
  2. 测试里手动创建的sessionMock和MainClass内部实例化的session实例完全没有绑定关系,就算原方法正常执行,调用的也是内部真实创建的session对象的方法,不会走到mock实例上,断言不可能成立。
  3. 贴出的MainClass代码本身有问题:session是定义在函数外的普通常量,没有挂载到this上,原代码执行到this.session.deleteEmpty()时本就会因为拿不到session对象报错。

修复方式
  • 不要直接stub整个foo方法,仅stub foo方法内部try块中会触发异常的依赖方法,让它抛出指定错误,保证foo的原有逻辑(包括catch块分支)可以正常执行。
  • 对Session构造函数做stub,让MainClass内部new出来的Session实例就是提前创建的sessionMock,这样才能监听到实例上的方法调用。如果是类内实例化的场景,优先用依赖注入的方式管理Session实例,更方便测试。
  • 修正MainClass的属性挂载逻辑,将实例化后的session挂到类实例属性上,保证this.session可以正确取到对应的实例对象。

修正后的测试参考:

// stub Session构造函数,所有new Session()都返回mock实例
const sessionMock = Sinon.createStubInstance(Session);
sandbox.stub(global, 'Session').returns(sessionMock);
// 重新初始化MainClass实例,保证内部创建的session是mock对象
const mainIns = new MainClass();
let thrown: Error | undefined = undefined;

// 仅stub foo内部try块里会抛错的依赖方法,不替换foo本身逻辑
sandbox.stub(internalService, 'query').throws(new Error('mock test error'));

try {
    await mainIns.foo();
} catch(error) {
    thrown = error;
}

// 此时两个断言都可正常校验
expect(sessionMock.deleteEmpty).to.have.been.calledOnce;
expect(thrown).to.not.be.undefined;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:57:12