Unit Test with Mongoose
Mongoose model
(your Issue
) returns a new instance of the Query
object. The new query
instance has access to the exec
method through the prototype
. (mongoose 3.8~)
If you want to return an error you can write:
sinon.stub(mongoose.Query.prototype, "exec").yields({ name: "MongoError" }, null);
Using mocha with chaijs and sinonjs in my node code something like this method works for me:
var should = require('chai').should(),sinon = require('sinon'),mongoose = require('mongoose');it('#issues() handles mongoosejs errors with 403 response code and a JSON error message', function (done) {// mock requestvar request = {};// mock responsevar response = {};response.setHeader = function(header) {};response.send = function (responseCode, jsonObject) { responseCode.should.equal(403); jsonObject.stats.should.equal('error'); // add a test for "error:": exception done();}var mockFind = { sort: function(sortOrder) { return this; }, exec: function (callback) { callback('Error'); }}// stub the mongoose find() and return mock find mongoose.Model.find = sinon.stub().returns(mockFind);// run functionissues(request, response);});
I'm not sure how to test the Content-Type, and I haven't tested this code myself, but I'm happy to help out if it doesn't work. It seems to make sense to me. Basically we just created a callback so we could move the response.send
out of the actual custom logic, then we can test via that callback. Let me know if it doesn't work or make sense. You can use the links that the other guys posted to prevent having to connect to the db.
Issue = mongoose.model("Issue", { identifier: String, date: String, url: String, name: String, thumbnailURL: String }); function issues(callback, request, response) { Issue.find().sort('number').exec(function(error, items) { if (error) { callback(403, {"status": "error", "error:": exception}); } else { callback(200, {"issues": items}); } }); } //Note: probably don't need to make a whole new `sender` function - depends on your taste function sender(statusCode, obj) { response.setHeader('Content-Type', 'text/json'); response.send(statusCode, obj); } //Then, when you want to implement issues issues(sender, request, response); //The tests - will depend on your style and test framework, but you get the idea function test() { //The 200 response issues(function(code, obj) { assert(code === 200); assert(obj.issues === ??); //some testable value, or just do a truthy test //Here, you can also compare the obj.issues item to the proper date-sorted value }); //The error response issues(function(code, obj) { assert(code === 403); assert(code.status === 'error'); }); }