有没有办法存根Mongoose模型的虚拟属性?
假设Problem
是模型类,difficulty
是虚拟属性。 delete Problem.prototype.difficulty
返回false,属性仍然存在,所以我不能用我想要的任何值替换它。
我也试过
var p = new Problem();
delete p.difficulty;
p.difficulty = Problem.INT_EASY;
它不起作用。
将undefined分配给Problem.prototype.difficulty
或使用sinon.stub(Problem.prototype, 'difficulty').returns(Problem.INT_EASY);
会抛出异常“TypeError:无法读取未定义的属性'范围',同时执行
var p = new Problem();
sinon.stub(p, 'difficulty').returns(Problem.INT_EASY);
会抛出错误“TypeError:尝试将字符串属性难度换行为函数”。
我的想法已经不多了。帮帮我!谢谢!
答案 0 :(得分:2)
mongoose internally uses Object.defineProperty
适用于所有媒体资源。由于它们被定义为不可配置,因此您无法delete它们,也不能re-configure它们。
但是,您可以做的是覆盖模型的get
和set
方法,这些方法用于获取和设置任何属性:
var p = new Problem();
p.get = function (path, type) {
if (path === 'difficulty') {
return Problem.INT_EASY;
}
return Problem.prototype.get.apply(this, arguments);
};
或者,使用sinon.js的完整示例:
var mongoose = require('mongoose');
var sinon = require('sinon');
var problemSchema = new mongoose.Schema({});
problemSchema.virtual('difficulty').get(function () {
return Problem.INT_HARD;
});
var Problem = mongoose.model('Problem', problemSchema);
Problem.INT_EASY = 1;
Problem.INT_HARD = 2;
var p = new Problem();
console.log(p.difficulty);
sinon.stub(p, 'get').withArgs('difficulty').returns(Problem.INT_EASY);
console.log(p.difficulty);
答案 1 :(得分:0)
截至2017年底和当前的Sinon版本,只能通过以下方式实现一些参数(例如,只有mongoose模型上的虚拟)的存根
const ingr = new Model.ingredientModel({
productId: new ObjectID(),
});
// memorizing the original function + binding to the context
const getOrigin = ingr.get.bind(ingr);
const getStub = S.stub(ingr, 'get').callsFake(key => {
// stubbing ingr.$product virtual
if (key === '$product') {
return { nutrition: productNutrition };
}
// stubbing ingr.qty
else if (key === 'qty') {
return { numericAmount: 0.5 };
}
// otherwise return the original
else {
return getOrigin(key);
}
});
该解决方案的灵感来自于一系列不同的建议,包括@Adrian Heine的建议