Reputation: 1158
I have written own thin mongodb wrapper for Node.js to eliminate code repetition.
However, I am having problems with asynchronous unit tests run with Mocha and Should.
What happens is that any thrown exception by Should library is being caught by MongoDB driver instead of Mocha.
I.e., neither Mocha catches the error, nor done() function gets called. As a consequence, Mocha prints out an error Error: timeout of 2000ms exceeded
.
Snippet of wrapper module db.js
var mongodb = require('mongodb').MongoClient;
exports.getCollection = function(name, callback) {
mongodb.connect(dbConfig.dbURI, {auto_reconnect: true}, function(err, db) {
if (err)
return callback(err, null);
db.collection(name, {strict: true}, callback);
});
};
Mocha test.js
var should = require('should');
var db = require('./db.js');
describe('Collections', function() {
it.only('should retrieve user collection', function(done) {
db.getCollection('user', function(err, coll) {
should.not.exist(err);
coll.should.be.a('object');
// HERE goes an assertion ERROR
coll.collectionName.should.equal('user123');
done();
});
});
});
The same behaviour can be simulated by this simple test.js
var should = require('should');
var obj = {
call: function(callback) {
try {
console.log('Running callback(null);');
return callback(null);
}
catch(e) {
console.log('Catched an error:', e);
}
}
};
describe('Test', function() {
it('should catch an error', function(done) {
obj.call(function(err) {
should.exist(err);
done();
});
});
});
Is there any way to workaround the issue? There must be a way to test such code.
Upvotes: 1
Views: 262
Reputation: 1158
Just by an accidental luck I spotted a GitHub fork dealing with a different problem, but the code lead me to realise I can use a simple trick to make Mocha to catch the assert exceptions:
describe('Test', function() {
it('should catch an error', function(done) {
obj.call(function(err) {
try {
should.exist(err);
done();
} catch (err) {
done(err);
}
});
});
});
I.e. wrapping the should
calls into try/catch
block and calling done(err)
in the catch section does exactly what is expected :
done()
function accepting an error argumentUpvotes: 1