我想将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 guide和this one之后尝试了Mockery,但这比我认为应该是必要的设置更多,让我质疑花时间隔离它的价值分贝。
我的印象是,这一切都与mongoose实施save
的神秘方式有关。我已经使用npm hooks
读了一些关于它的内容,这使得save
方法变得很简单。
我也听说过mockgoose,但我还没有尝试过这个解决方案。任何人都有这个策略的成功? [编辑:事实证明,mockgoose提供了一个内存数据库,易于设置/拆卸,但它无法解决存根问题。]
非常感谢您对如何解决此问题的任何见解。
答案 0 :(得分:6)
这是我开发的最终配置,它使用了sinon和mockery的组合:
b = parseFloat(document.getElementById('someElement').style.left)
答案 1 :(得分:2)
你试过了吗?
sinon.stub(userModel.prototype, 'save')
此外,在测试中调用辅助函数的位置是什么?看起来您将函数定义为utils模块,但将其称为控制器对象的方法。我假设这与该错误消息无关,但它确实使得更难弄清楚存根被调用的时间和地点。