茉莉花 – 在构造函数中侦听方法调用

我想testing是否在我的Javascript对象构造函数中调用以下方法。 从我在Jasmine文档中看到的,我可以窥探一个构造函数方法,并且可以在一个对象被实例化之后监听方法,但是我似乎无法在构造对象之前窥探一个方法。

物体:

Klass = function() { this.called_method(); }; Klass.prototype.called_method = function() { //method to be called in the constructor. } 

我想在规范中做这样的事情:

 it('should spy on a method call within the constructor', function() { spyOn(window, 'Klass'); var obj = new Klass(); expect(window.Klass.called_method).toHaveBeenCalled(); }); 

直接对原型法进行间谍:

 describe("The Klass constructor", function() { it("should call its prototype's called_method", function() { spyOn(Klass.prototype, 'called_method'); //.andCallThrough(); var k = new Klass(); expect(Klass.prototype.called_method).toHaveBeenCalled(); }); }); 

大体上,我同意戴夫牛顿的答案。 但是,您应该考虑这种方法的一些边缘情况。

对Dave的解决scheme进行一个变更,再用另一个testing案例:

 // production code var Klass = function() { this.call_count = 0; this.called_method(); }; Klass.prototype.called_method = function() { ++this.call_count; }; // test code describe("The Klass constructor", function() { it("should call its prototype's called_method", function() { spyOn(Klass.prototype, 'called_method'); var k = new Klass(); expect(k.called_method).toHaveBeenCalled(); }); it('some other test', function() { var k = new Klass(); expect(k.call_count).toEqual(1); }); }); 

第二个testing会失败,因为第一个testing的间谍设置​​在testing范围内持续到第二个方法; called_method不增加call_count,所以this.call_count不等于1.也可以想出带误报的情况 – testing通过,不应该。

最重要的是,由于间谍依然存在,所创build的Klass实例越多,间谍将消耗的内存越大,因为间谍会将每次调用logging到called_method。 这在大多数情况下可能不是问题,但是您应该意识到这一点,以防万一。

解决这个问题的一个简单的方法是确保间谍在使用后被移除。 它可以看起来有点丑,但是这样的工作:

 // test code describe("The Klass constructor", function() { it("should call its prototype's called_method", function() { var spy = jasmine.createSpy('called_method'); var method = Klass.prototype.called_method; Klass.prototype.called_method = spy; var k = new Klass(); expect(spy).toHaveBeenCalled(); Klass.prototype.called_method = method; }); 

[注 – 完成一些意见]更好的解决scheme是改变你编写生产代码的方式,使代码更容易testing。 通常,窥探原型可能是一种可以避免的代码味道。 注入它们,而不是在构造函数中实例化依赖关系。 不要在构造函数中进行初始化,请遵循适当的init方法。