使用Sinon模拟Mongoose模型

6

我正在尝试为这个对象中使用的mongoose依赖项进行存根:

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;

使用这个问题的答案,我尝试做了以下操作:

mongoose = require 'mongoose'
sinon.stub mongoose.Model, 'save'

但是我遇到了错误:

类型错误:尝试将未定义的属性“save”作为函数进行包装

我也尝试了这个:

sinon.stub PageSchema.prototype, 'save'

然后我遇到了这个错误:

类型错误:应该包装对象的属性

有人可以帮忙吗?我做错了什么吗?

3个回答

7
我已经分析了mongoose源代码,不认为这是可能的。Save函数没有在模型上定义,而是通过hooks npm动态生成,从而实现pre/post middleware功能。
然而,您可以像这样在实例上存根保存:
page = new Page();
sinon.stub(page, 'save', function(cb){ cb(null) })

更新:桩数据 pageModel

首先,您需要将 pageModel 设置为 Page 的自有属性,使其可访问(this.pageModel = xxx)。然后,您可以按照下面所示的方式对其进行桩数据:

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");
});

我尝试做这个,但是我收到一个错误,说:Object save没有方法'save'。我调用了mongoose.model('Page'),创建了一个实例,然后我对它进行了存根处理。 - thitemple
嗯...你是在试图存根pageModel.save吗? - Milovan Zogovic
我想要的就是避免访问数据库,无论如何。我最初尝试了存根mongoose.model。现在我正在尝试存根pageModel.save。 - thitemple
我并不喜欢公开PageSchema,但是这种方式可行。 - thitemple

6
我建议您使用mock而不是stub,这将检查原始对象上的方法是否真正存在。
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);

看看sinon-mongoose。只需几行代码,您就可以期望在Mongoose模型和文档上使用链式方法(存储库中有可工作的示例)。


希望我明天记得给这个投票。多么棒的模拟包。让我省了很多麻烦。 - SomeDutchGuy
感谢 @RuudVerhoef :) - Gon

0
page = new Page();
sinon.stub(page, 'save', function(cb){ cb(null) })

上面的代码已经过时了。

请尝试按照以下方式为您的存根添加虚函数 -

sinon.stub(page, 'save').callsFake(function(cb){
      // do your Fake code
      cb(null)
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接