在模型上存储mongoose save方法

时间:2015-03-03 05:08:59

标签: unit-testing mongoose mocha

我想将Mongoose模型可用的save方法存根。这是一个样本模型:

/* model.js */
var mongoose = require('mongoose');
var userSchema = mongoose.Schema({
  username: {
    type: String,
    required: true
  }
});
var User = mongoose.model('User', userSchema);
module.exports = User;

我有一些调用save方法的辅助函数。

/* utils.js */
var User = require('./model');
module.exports = function(req, res) {
  var username = req.body.username;
  var user = new User({ username: username });
  user.save(function(err) {
    if (err) return res.end();
    return res.sendStatus(201);
  });
};

我想检查使用单元测试在我的帮助函数中调用user.save

/* test.js */
var mongoose = require('mongoose');
var createUser = require('./utils');
var userModel = require('./model');

it('should do what...', function(done) {
  var req = { username: 'Andrew' };
  var res = { sendStatus: sinon.stub() };
  var saveStub = sinon.stub(mongoose.Model.prototype, 'save');
  saveStub.yields(null);

  createUser(req, res);

  // because `save` is asynchronous, it has proven necessary to place the
  // expectations inside a setTimeout to run in the next turn of the event loop
  setTimeout(function() {
    expect(saveStub.called).to.equal(true);
    expect(res.sendStatus.called).to.equal(true);
    done();
  }, 0)
});

我从here发现了var saveStub = sinon.stub(mongoose.Model.prototype, 'save')

除非我尝试向saveStub添加内容,否则一切正常与saveStub.yields(null)。如果我想模拟使用save传递给saveStub.yields('mock error')回调的错误,我会收到此错误:

TypeError: Attempted to wrap undefined property undefined as function

堆栈跟踪完全没有用。

我已完成的研究

我尝试重构我的模型以获得对基础用户模型的访问权限,如建议的here。这给我带来了同样的错误。这是我尝试的代码:

/* in model.js... */
var UserSchema = mongoose.model('User');
User._model = new UserSchema();

/* in test.js... */
var saveStub = sinon.stub(userModel._model, 'save');

我发现this solution对我来说根本不起作用。也许这是因为我以不同的方式设置我的用户模型?

我还在this guidethis one之后尝试了Mockery,但这比我认为应该是必要的设置更多,让我质疑花时间隔离它的价值分贝。

我的印象是,这一切都与mongoose实施save的神秘方式有关。我已经使用npm hooks读了一些关于它的内容,这使得save方法变得很简单。

我也听说过mockgoose,但我还没有尝试过这个解决方案。任何人都有这个策略的成功? [编辑:事实证明,mockgoose提供了一个内存数据库,易于设置/拆卸,但它无法解决存根问题。]

非常感谢您对如何解决此问题的任何见解。

2 个答案:

答案 0 :(得分:6)

这是我开发的最终配置,它使用了sinon和mockery的组合:

b = parseFloat(document.getElementById('someElement').style.left)

答案 1 :(得分:2)

你试过了吗?

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

此外,在测试中调用辅助函数的位置是什么?看起来您将函数定义为utils模块,但将其称为控制器对象的方法。我假设这与该错误消息无关,但它确实使得更难弄清楚存根被调用的时间和地点。