使用jasmine.spyOn进行mongoose模式方法

时间:2014-04-29 23:48:14

标签: node.js mongoose jasmine

我无法让茉莉花间谍为我的mongoose文件工作。我在我的用户架构中设置了一个方法,如下所示:

User.methods.doSomething = function() {
   // implementation
}

用户是我正在测试的模型的依赖项,我想确保正确调用doSomething。在我的测试中,我有类似的东西:

spyOn(User.schema.methods, 'doSomething')

如果我注销User.schema.methods.doSomething我得到了我期望的功能但是当我运行调用该方法的代码时,调用原始实现而不是间谍。我也做不到:

spyOn(userInstance, 'doSomething')

在我的测试中,因为userInstance没有暴露,我真的想避免暴露它。基本上我想在User文档(实例?)原型上设置一个间谍。这可能吗?

2 个答案:

答案 0 :(得分:4)

Mongoose正在将模式中定义的方法复制到模型原型中,并且只使用那些方法。所以即使

User.schema.methods.doSomething === User.prototype.doSomething

如果你设置:

spyOn(User.schema.methods, 'doSomething')

它不会被叫 - User.prototype.doSomething会。你的猜测是正确的,你应该使用:

spyOn(User.prototype, 'doSometing');

如果您想在设置间谍后调用原始方法(我为之摔倒),请不要忘记使用and.callThrough

答案 1 :(得分:0)

不幸的是,我无法让spyOn处理模型原型。这可能是因为我的模特'实际上是一个猫鼬子文档。

相反,我选择了代理功能,而我却用它来代替。这是一个额外的函数调用,这有点烦人,但它有效。

// index.js
Controller._performClone = function(doc) {
  return doc.clone();
};

Controller.clone = function(id) {
  var child = parent.children.id(req.params.id);
  return Controller._performClone(child);
};


// spec.js
describe('Cloning', function() {
  it('should clone a document', function(done) {
    spyOn(Controller, '_performClone').and.returnValue('cloned');
    var rtn = Controller.clone('1');
    expect(rtn).toBe('cloned');

    // `correctChild` is the one you expect with ID '1'
    expect(Controller._performClone).toHaveBeenCalledWith(correctChild);
  });
});