I'm trying to Unit test my Mongoose connection code, which involves an open handler and an error handler. If I trigger the open handler by connecting to the database, then disconnect, then attempt to trigger the error handler using an invalid connection string, the error handler does not fire.
Here's a high-level outline of my connection code flow:
Here's my connection code, simplified as much as possible.
/**
* Connect to the database and set up the schema.
* @param conStr The mongoose connection string.
* @param openCallback A callback function(mongoose, err) that fires
* when the database connection is ready.
*/
module.exports = function(conStr, openCallback)
{
var mongoose = require('mongoose');
// Connect using the passed-in connection string.
mongoose.connect(conStr);
// Connection error.
mongoose.connection.on('error', function()
{
console.log('Connection error');
openCallback(mongoose, 'MongDB connection error.');
mongoose.disconnect();
});
// Fire the callback on open (normally compile the schemas).
mongoose.connection.once('open', function()
{
console.log('Connection open');
// All set, fire the callback
openCallback(mongoose, null);
});
};
I'd like to test the open listener and the error listener using Jasmine 2.0. If I call the above function using a valid connection string, the open listener fires as expected. If I then call the above function with an invalid connection string, the error listener never fires.
describe('DB test suite.', function()
{
var mongoose;
// Start from scratch after each spec (disconnect, etc.).
afterEach(function(done)
{
// Clear any open listeners and disconnect.
mongoose.connection.removeAllListeners('open');
mongoose.disconnect(done);
});
// Valid constr.
it('should connect.', function(done)
{
require('../DB.js')('mongodb://localhost/DiscGolfDev', function(mong, errMsg)
{
mongoose = mong;
expect(errMsg).toBe(null);
expect(mongoose.connection.readyState).toBe(1); // connected.
done();
});
});
// Invalid constr.
it('should fail to connect.', function(done)
{
// Wrong port.
require('../DB.js')('mongodb://localhost:1337/DiscGolfDev', function(mong, errMsg)
{
mongoose = mong;
expect(errMsg).toBe('MongDB connection error.');
expect(mongoose.connection.readyState).toBe(0); // disconnected.
done();
});
});
});
The second test fails with a Jasmine timeout: Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
This error occurs even if I adjust the timeout interval to 100+ seconds.
If I reverse the order of the above tests then they work as expected. Reversing the order isn't an option for me however; I have a few scenario-type tests which connect to and disconnect from the database. If any of these scenarios runs before my the above spec, it fails. (Not only that but I'm of the opinion that tests should be commutative.)
Thanks for the help.