Stubbing a Mongoose model using Sinon
I've analysed mongoose source and don't think this is possible. Save function is not defined on model, but dynamically generated by hooks npm which enables pre/post middleware functionality.
However, you can stub save on instance like this:
page = new Page();sinon.stub(page, 'save', function(cb){ cb(null) })
UPDATE: Stubbing out pageModel
First, you need to make pageModel
accessible by setting it as own property of Page
(this.pageModel = xxx
). Then, you can stub it like shown bellow:
mongoose = require('mongoose');mongoose.connect('mongodb://localhost/test');mongoose.set('debug', true);schema = new mongoose.Schema({title: String});mongoose.model('Page', schema);var Page = function(db) { var mongoose = db || require('mongoose'); if(!this instanceof Page) { return new Page(db); } var PageSchema = mongoose.model('Page'); this.pageModel = new PageSchema(); function save(params, cb) { console.log("page.save"); this.pageModel.set(params); this.pageModel.save(function (err, product) { console.log("pageModel.save"); cb(err, product); }); } Page.prototype.save = save;};page = new Page();sinon = require('sinon');sinon.stub(page.pageModel, 'save', function(cb){ cb("fake error", null);});page.save({ title: 'awesome' }, function (err, product) { if(err) return console.log("ERROR:", err); console.log("DONE");});
I recommend you to use mock
instead of stub
, that will check the method really exists on the original object.
var page = new Page();// If you are using callbacks, use yields so your callback will be calledsinon.mock(page) .expects('save') .yields(someError, someResult);// If you are using Promises, use 'resolves' (using sinon-as-promised npm) sinon.mock(page) .expects('save') .resolves(someResult);
Take a look to sinon-mongoose. You can expects chained methods (on both, Mongoose Models and Documents) with just a few lines (there are working examples on the repo).