Stubbing a Mongoose model with Sinon

只谈情不闲聊 提交于 2019-11-27 14:37:48

There are two ways to accomplish this. The first is

var mongoose = require('mongoose');
var myStub = sinon.stub(mongoose.Model, METHODNAME);

If you console log mongoose.Model you will see the methods available to the model (notably this does not include lte option).

The other (model specific) way is

var myStub = sinon.stub(YOURMODEL.prototype.base.Model, 'METHODNAME');

Again, the same methods are available to stub.

EDIT: Some methods such as save are stubbed as follows:

var myStub = sinon.stub(mongoose.Model.prototype, METHODNAME);
var myStub = sinon.stub(YOURMODEL.prototype, METHODNAME);

Take a look to sinon-mongoose. You can expects chained methods with just a few lines:

sinon.mock(YourModel).expects('find')
  .chain('limit').withArgs(10)
  .chain('exec');

You can find working examples on the repo.

Also, a recommendation: use mock method instead of stub, that will check the method really exists.

save is not a method on the model, it's a method on the document (instance of a model). Stated here in mongoose docs.

Constructing documents

Documents are instances of our model. Creating them and saving to the database is easy

Therefore, it will always be undefined if you're using your model to mock a save()

Going along with @Gon's answer, using sinon-mongoose & factory-girl with Account being my model:

Will not work

var AccountMock = sinon.mock(Account)

AccountMock
  .expects('save') // TypeError: Attempted to wrap undefined property save as function
  .resolves(account)

Will work

var account = { email: 'sasha@gmail.com', password: 'abc123' }

Factory.define(account, Account)
Factory.build('account', account).then(accountDocument => {
  account = accountDocument

  var accountMock = sinon.mock(account)

  accountMock
    .expects('save')
    .resolves(account)

  // do your testing...
})

Instead of the whole object, try:

sinon.stub(YOURMODEL.prototype, 'save')

Make sure YOURMODEL is the class not the instance.

Tangentially-related, but relevant...

I needed to mock a custom model method like:

myModelSchema.methods.myCustomMethod = function() {....}

To create a stub I did:

myCustomMethodStub = sinon.stub(MyModel.schema.methods, 'myCustomMethod').callThrough();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!