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

用Chai和Mocha测试socket.io的addBooking错误抛出时遇AssertionError如何解决?

嘿,我来帮你搞定这个测试问题!

首先得搞清楚你为啥会遇到这个错误:should.throw()是用来测试同步函数抛出的错误的,但addBooking返回的是一个Promise——当数据库插入失败时,它会通过reject返回错误,而不是同步抛出throw。你直接把一个pending状态的Promise传给should.throw(),它自然会报错说“预期是个函数,结果拿到了Promise对象”。

下面给你两种正确的测试方案,按需选择:


方案一:用Chai-as-promised插件(推荐,写法更简洁)

这个插件专门用来简化Promise的断言,能让你的测试代码更直观。

  1. 先安装插件:
npm install chai-as-promised --save-dev
  1. 在测试文件里启用它:
const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
const should = chai.should();
  1. 测试addBooking的reject场景:
// 用Promise链式调用写法
it('应该在数据库插入失败时reject错误', () => {
  // 这里要传入会触发插入失败的测试数据,或者提前mock数据库方法让它返回错误
  return addBooking(/* 错误测试数据 */)
    .should.be.rejectedWith('数据库插入失败'); // 这里填你预期的错误信息或Error类型
});

// 或者用async/await写法(更符合现代JS习惯)
it('应该在数据库插入失败时reject错误', async () => {
  await addBooking(/* 错误测试数据 */)
    .should.be.rejectedWith(Error); // 也可以直接断言错误类型
});

方案二:不用插件,手动处理Promise的catch回调

如果不想额外装插件,也可以直接用Promise的catch结合Chai断言,再配合Mocha的done回调:

it('应该在数据库插入失败时reject错误', (done) => {
  addBooking(/* 错误测试数据 */)
    .catch((err) => {
      // 在这里写你的断言
      err.should.exist;
      err.message.should.equal('数据库插入失败');
      done(); // 告诉Mocha测试完成
    })
    .catch(done); // 捕获断言本身的错误,确保测试失败时能正确上报
});

额外提示:如果要测试socket.io的request事件逻辑

如果你还要测试socket.io的request事件监听代码(比如触发事件后是否正确处理了addBooking的错误),可以用Sinon来mock socket实例,比如:

const sinon = require('sinon');

it('当addBooking失败时,socket应该正确返回错误', (done) => {
  // mock一个socket对象,监听emit方法
  const socket = {
    on: sinon.stub(),
    emit: sinon.stub()
  };

  // 假设你的request事件处理逻辑是这样的,先绑定事件
  socket.on('request', (data, callback) => {
    addBooking(data)
      .then(result => callback(null, result))
      .catch(err => callback(err));
  });

  // 触发request事件,传入会导致失败的数据
  socket.emit('request', /* 错误测试数据 */, (err) => {
    err.should.exist;
    err.message.should.equal('数据库插入失败');
    done();
  });
});

核心思路就是:同步错误用should.throw(),Promise的reject要用异步断言方式,别把两者搞混啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:29:40