使用 JavaScript 和 sinon 你如何监视构造函数中调用的方法?

Using JavaScript and sinon How do you spy on methods called in the constructor?

我真的需要以下代码的帮助 - 这不是从我的程序中粘贴的,它是我想出来的,但我认为它清楚地说明了问题(并且我相信它是完全准确的)。当我请求 "spy.called" 的值时,它会忽略在构造函数中进行的调用。我该如何编写代码,以便间谍注册构造函数中的调用?

或者如果不可能,我应该采取什么方法?非常感谢示例代码 - 非常感谢 - 一整天都在用这个敲我的脑袋!

function MyClass() {
  var self = this;
  this.myFunc = function() {
    console.log("hi");
  }
  function init() {
    self.myFunc();
  }
  init();
}


var spy = sinon.spy(new MyClass(), "myFunc");
console.log(spy.called);  // true if the spy was called at least once
// ABOVE OUTPUTS FALSE - IT FAILS TO REGISTER THE CALL IN THE CONSTRUCTOR!
spy.myFunc();
console.log(spy.called);
// ABOVE OUTPUTS TRUE AS EXPECTED

我认为您应该稍微重新设计一下 class。您可以在构造函数参数中接受 myFunc(仅当从使用角度来看有意义时),或者您可以在 MyClass 的原型上设置它:

function MyClass() {
    function init() {
        this.myFunc();
    }
    init();
}

MyClass.prototype.myFunc = function() {
    console.log("hi");
}

var spy = sinon.spy(MyClass.prototype, "myFunc");
new MyClass();
console.log(spy.called);

这里的问题是当方法myFunc被调用时间谍还不存在。您的代码相当于:

var c = new MyClass()
var spy = sinon.spy(c, "myFunc");

很明显,当调用构造函数时,间谍没有到位。

要解决此问题,您可以将方法 myFunc 移动到 MyClass 对象的原型中,然后侦测原型中的方法。

例如:

function MyClass() {
  this.init();
}

MyClass.prototype.myFunc = function() {
    console.log("hi");
}

MyClass.prototype.init = function() {
   this.myFunc();
}

var myFuncSpy = sinon.spy(MyClass.prototype, "myFunc");
var initSpy = sinon.spy(MyClass.prototype, "init");

var c = new MyClass();
console.log(myFuncSpy.called); // TRUE
console.log(initSpy.called);  // TRUE

JSFIDDLE:http://jsfiddle.net/och191so/1/ 打开控制台查看结果。