I am trying to stub the mongoose dependency used in this object:
var Page = function(db) {
var mongoose = db || require('mongoose');
if(!this instanceof Page) {
return new Page(db);
}
function save(params) {
var PageSchema = mongoose.model('Page');
var pageModel = new PageSchema({
...
});
pageModel.save();
}
Page.prototype.save = save;
}
module.exports = Page;
Using the answer for this question, I've tried doing this:
mongoose = require 'mongoose'
sinon.stub mongoose.Model, 'save'
But I got the error:
TypeError: Attempted to wrap undefined property save as function
I also tried this:
sinon.stub PageSchema.prototype, 'save'
And then I got the error:
TypeError: Should wrap property of object
Can anyone help with this? What am I doing wrong?
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 called
sinon.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).
page = new Page();
sinon.stub(page, 'save', function(cb){ cb(null) })
Above code is deprecated.
Please try to add fake function for your stub as below -
sinon.stub(page, 'save').callsFake(function(cb){
// do your Fake code
cb(null)
})
来源:https://stackoverflow.com/questions/16727616/stubbing-a-mongoose-model-using-sinon