为何我的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;
问题根因
- 测试中直接stub了整个
MainClass.foo方法,相当于完全替换了foo的原有实现,原方法catch块中调用this.session.deleteEmpty()的逻辑根本不会执行,自然不可能触发deleteEmpty的调用。 - 测试里手动创建的
sessionMock和MainClass内部实例化的session实例完全没有绑定关系,就算原方法正常执行,调用的也是内部真实创建的session对象的方法,不会走到mock实例上,断言不可能成立。 - 贴出的
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
相关产品推荐
相关产品推荐

