问题描述
我正在编写一个单元测试来测试我的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。