测试失败时不会调用Done()

人气:540 发布:2022-10-16 标签: node.js unit-testing postgresql chai mocha.js

问题描述

我正在编写一个单元测试来测试我的postgres模式。我使用的是node-pg、mocha、sinon和chai。

这是可行的-测试通过,没有问题:

describe('When adding a user', ()=> {
  it('should reject since email is used somewhere else', (done)=> {
    pool.query(`INSERT INTO users(email, id, token)
               VALUES($1, $2, $3)`, ['foo@email.com', '12346', 'fooToken'])
    .then((result)=> {
      console.log('nothing in here runs, you will not see this');
      done()
    })
    .catch((result) => {
      result.constraint.should.have.string('email_already_exists');
      done();
    })
  })
});
但为了确保不会得到假阳性,我将断言更改为result.constraint.should.not.have.string('email_already_exists');,以故意使测试失败。

我得到的不是测试失败,而是Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.

我得到的是什么?

推荐答案

如果您仍然希望使用Promises来完成此操作,则问题在于,Promise中未处理的异常不会被传播,而是被静默忽略。因此,没有人调用Mocha的done方法,从而导致超时。

按照文档here将侦听程序附加到节点的unhandledRejection事件应说明这一点。

如果修改原始代码并添加对Promise的done方法的调用(这不是Mocha的done方法!),那么您将能够捕获所有错误并将它们传递给Mocha的done方法:

it('tests something', done => {
    pool.query('...')
    .then(result => {
        // ...
     })
    .catch(result => {
        // assertion that fails
    })
    .done(result => {}, error => { done(error); });
});

请注意,Promise.done()还不是该标准的一部分,但许多实现都支持它。例如,参见here。

399