When chai.expect assertions fail,
they normally fail the test
and the negative result gets added to the report
for the test runner (in this case mocha).
However, when I use a generator function wrapped using co.wrap(),
as seen below,
something strange happens:
when the assertions pass, everything runs just fine.
When the assertions fail, however, the test times out.
How can co be used together with mocha+chai?
it('calls API and then verifies database contents', function(done) {
var input = {
id: 'foo',
number: 123,
};
request
.post('/foo')
.send(input)
.expect(201)
.expect({
id: input.id,
number: input.number,
})
.end(function(err) {
if (!!err) {
return done(err);
}
// Now check that database contents are correct
co.wrap(function *() {
var dbFoo = yield foos.findOne({
id: input.id,
});
continueTest(dbFoo);
})();
function continueTest(dbFoo) {
//NOTE when these assertions fail, test times out
expect(dbFoo).to.have.property('id').to.equal(input.id);
expect(dbFoo).to.have.property('number').to.equal(input.number);
done();
}
});
});
Solution:
The problem arose due to co.wrap() swallowing the exception thrown by expect(), not allowing it bubble up to where it needed to for mocha to find it, as pointed out by @Bergi below.
The solution was to use co() instead of co.wrap(), and add .catch() and pass that the done callback, as seen below.
// Now check that database contents are correct
co(function *() {
var dbFoo = yield foos.findOne({
id: input.id,
});
continueTest(dbFoo);
}).catch(done);
co.wrapcatches exceptions from the generator, and rejects the returned promise. It "swallows" the error that is thrown from the assertions incontinueTest. Btw, instead of using.wrapand immediately calling it, you can just callco(…).or
Btw, to use co properly you'd put all your asynchronous functions in a single generator: