Reputation: 11064
I am writing a unit test to test my postgres schema. I am using node-pg, mocha, sinon, and chai.
This works - the test passes with no issues:
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)`, ['[email protected]', '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();
})
})
});
But to make sure I am not getting a false positive, I change the assert to result.constraint.should.not.have.string('email_already_exists');
to purposely make the test fail.
Instead of the test failing, I get Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
.
What am I getting this?
Upvotes: 0
Views: 287
Reputation: 1614
If you would still like to use Promises for this, the problem is that unhandled exceptions in Promises are unfortunately not propagated but rather are silently ignored. As a result, no one calls Mocha's done
method, leading to the timeout.
Attaching a listener to Node's unhandledRejection
event as documented here should demonstrate this.
If you modify your original code and add a call to the Promise's done
method (this isn't Mocha's done
method!), then you'll be able to catch all errors and pass them to Mocha's done
method:
it('tests something', done => {
pool.query('...')
.then(result => {
// ...
})
.catch(result => {
// assertion that fails
})
.done(result => {}, error => { done(error); });
});
Note that Promise.done()
isn't (yet) part of the standard, but is nonetheless supported by many implementations. See for example here.
Upvotes: 3
Reputation: 11064
Answer:
The promise chain for node-pg causes this strange issue during testing. If I work off of callback, then no issue:
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($1, $2, $3)`, ['[email protected]', '12346', 'fooToken'], callback)
})
});
Upvotes: 0