测试失败时不会调用 done()
Test will not call done() when failing
我正在编写单元测试来测试我的 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(, , )`, ['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.
。
我得到了什么?
答案:
node-pg 的承诺链在 测试期间导致了这个奇怪的问题。如果我关闭回调,那么没问题:
describe('When adding a user', ()=> {
it('should reject since email is used somewhere else', (done)=> {
function callback(err, result) {
err.constraint.should.not.have.string('email_already_exists');
done();
}
pool.query(`INSERT INTO users(email, id, token)
VALUES(, , )`, ['foo@email.com', '12346', 'fooToken'], callback)
})
});
如果您仍想为此使用 Promises,问题是 Promises 中未处理的异常很遗憾不会传播,而是被静默忽略。结果没有人调用mocha的done
方法,导致超时
按照记录 here 将侦听器附加到 Node 的 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()
(目前)不是标准的一部分,但仍然受到许多实现的支持。例如参见 [=18=].
我正在编写单元测试来测试我的 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(, , )`, ['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.
。
我得到了什么?
答案:
node-pg 的承诺链在 测试期间导致了这个奇怪的问题。如果我关闭回调,那么没问题:
describe('When adding a user', ()=> {
it('should reject since email is used somewhere else', (done)=> {
function callback(err, result) {
err.constraint.should.not.have.string('email_already_exists');
done();
}
pool.query(`INSERT INTO users(email, id, token)
VALUES(, , )`, ['foo@email.com', '12346', 'fooToken'], callback)
})
});
如果您仍想为此使用 Promises,问题是 Promises 中未处理的异常很遗憾不会传播,而是被静默忽略。结果没有人调用mocha的done
方法,导致超时
按照记录 here 将侦听器附加到 Node 的 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()
(目前)不是标准的一部分,但仍然受到许多实现的支持。例如参见 [=18=].