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

Node.js单元测试:Sinon stub后Sequelize方法catch报错解决

解决方案:修复Sinon Stub导致的Promise catch报错

这个问题我太熟悉了!你遇到的报错根源在于Sinon stub的返回值类型不匹配——Sequelize的UserModel.create()本身返回的是一个Promise,但你用stub.returns(user)返回的是一个普通同步对象,根本没有.catch()方法,所以代码运行到这一步就报错了。

核心修复思路

把Sinon的returns()换成resolves(),因为resolves()会让stub返回一个处于resolved状态的Promise,完美匹配Sequelize原生方法的返回值类型,这样原代码中的.catch()就能正常调用了。

修改后的测试用例

it.only('Create New User', async () => { 
  // 用resolves替代returns,返回Promise对象
  const stub = sinon.stub(UserModel, "create").resolves(user); 
  const created = await UserService.createUser(user); 
  
  expect(stub.calledOnce).to.be.true;
  // 额外验证返回值是否符合预期(可选但推荐)
  expect(created).to.be.an.instanceOf(UserBOMapper);
});

额外:测试错误分支(catch块)

如果需要验证错误处理逻辑(也就是handleError是否被正确调用),可以用stub.rejects()返回一个rejected状态的Promise:

it('Handle error when creating user', async () => {
  const testError = new Error('Database creation failed');
  // 模拟create方法抛出错误
  const createStub = sinon.stub(UserModel, "create").rejects(testError);
  // Spy住handleError方法,验证是否被调用
  const errorSpy = sinon.spy(UserService, 'handleError');
  
  const created = await UserService.createUser(user);
  
  // 断言验证
  expect(createStub.calledOnce).to.be.true;
  expect(errorSpy.calledWith(testError)).to.be.true;
  expect(created).to.be.null;
  
  // 测试完成后恢复stub和spy,避免影响其他测试
  createStub.restore();
  errorSpy.restore();
});

为什么这能解决问题?因为resolves()和rejects()是Sinon专门为异步方法stub设计的API,它们会返回标准的Promise对象,完全兼容原代码中的await和.catch()调用,既保留了业务代码的错误处理逻辑,又能让测试正常通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 22:13:15