I have an Express route defined as follows (where app
is my Express app):
module.exports = function(app) {
var controller = require('../../app/controllers/experiment-schema');
app.route('/api/experiment-schemas/random').get(controller.random);
};
In that 'controller' file, I have this method:
exports.random = function (req, res, callback) {
ExperimentSchema.count({}, function (err, count) {
var rand = Math.floor(Math.random() * count);
ExperimentSchema.find({})
.skip(rand)
.limit(1)
.populate('mediaPool', 'artist title label')
.exec(function (err, schema) {
res.json(200, schema);
if (typeof callback === 'function') {
callback();
}
});
});
}
Here, ExperimentSchema
is a Mongoose model. Since the controller method hits the database, I'm passing in a callback in my test so that I can wait for those database calls to return and verify the return value. I'm doing this based on this question.
When I go to test the route, I'm testing with supertest
, actually making the HTTP call to the route. The problem is that when I do this, Express is injecting next
as the third argument to my random
method. Now, callback()
aliases next()
, and everything goes haywire. How can I test my route and my controller seperately?
The best way to test controller functions like that is to just mock the request and response data and export it to a test suite like mocha. Though it also seems like you will need to mock out your mongoose schema's as well. There is no easy way to test these components unless you want to mock the inputs for these functions.