Остановка модели Mongoose с Sinon

Я хочу создать заглушку для метода сохранения Mongoose в определенной модели, так что любой экземпляр моей модели, которую я создаю, вызовет заглушку вместо обычного метода сохранения Mongoose. Я понимаю, что единственный способ сделать это - заглушить всю модель следующим образом:

var stub = sinon.stub(myModel.prototype);

К сожалению, эта строка кода вызывает следующую ошибку:

TypeError: Cannot read property 'states' of undefined

Кто-нибудь знает, что здесь происходит не так?

Ответ 1

Есть два способа сделать это. Первый -

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

Если вы отключите log mongoose.Model, вы увидите доступные модели для модели (особенно это не включает параметр lte).

Другой (специфичный для модели) способ -

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

Опять же, те же методы доступны для заглушки.

EDIT: некоторые методы, такие как сохранение, заштрихованы следующим образом:

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

Ответ 2

Взгляните на sinon-mongoose. Вы можете ожидать цепных методов всего несколькими строками:

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

Вы можете найти рабочие примеры в репо.

Кроме того, рекомендуется использовать метод mock вместо stub, который будет проверять, действительно ли метод существует.

Ответ 3

save не является методом на модели, это метод документа (экземпляр модели). Указано здесь, в документах mongoose.

Построение документов

Документы являются примерами нашей модели. Создание их и сохранение в базе данных легко

Следовательно, он всегда будет undefined, если вы используете свою модель, чтобы издеваться над save()

Следуя ответам @Gon, используя sinon-mongoose и factory-girl с Account, являющимся моей моделью:

Не работает

var AccountMock = sinon.mock(Account)

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

Будет работать

var account = { email: '[email protected]', 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...
})

Ответ 4

Вместо всего объекта попробуйте:

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

Убедитесь, что YOURMODEL является классом, а не экземпляром.