首页 文章

对Mongoose模型的虚拟属性进行拼接

提问于
浏览
2

有没有办法存根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: Cannot read property 'scope' of undefined",同时执行

var p = new Problem();
  sinon.stub(p, 'difficulty').returns(Problem.INT_EASY);

会抛出错误“TypeError:尝试将字符串属性难度包装为函数” .

我的想法已经不多了 . 帮帮我!谢谢!

2 回答

  • 0

    所有属性的mongoose internally uses Object.defineProperty . 由于它们被定义为不可配置,因此您不能delete它们,也不能它们 .

    但是,您可以做的是覆盖模型的 getset 方法,这些方法用于获取和设置任何属性:

    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);
    
  • 2

    截至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的建议

相关问题