2

有没有办法存根猫鼬模型的虚拟属性?

假设Problem是一个模型类,并且difficulty是一个虚拟属性。delete Problem.prototype.difficulty返回 false,并且该属性仍然存在,因此我无法将其替换为我想要的任何值。

我也试过

var p = new Problem();
delete p.difficulty;
p.difficulty = Problem.INT_EASY;

它没有用。

将未定义分配给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:尝试将字符串属性难度包装为函数”。

我的想法不多了。帮帮我!谢谢!

4

2 回答 2

3

猫鼬在内部使用 Object.defineProperty所有属性。由于它们被定义为不可配置,因此您不能删除它们,也不能重新配置它们。

但是,您可以做的是覆盖用于获取和设置任何属性的模型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);
于 2013-09-14T21:12:55.373 回答
0

截至 2017 年底和当前的 Sinon 版本,仅存根部分参数(例如仅在 mongoose 模型上的 virtuals)可以通过以下方式实现

  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

于 2017-12-16T20:25:57.080 回答