2014-09-05 75 views
6

我想窺視一個構造函數,並告訴它使用jasmine調用了多少次。我通常會做這樣的事情的目標對象的方法:使用jasmine構造函數間諜

spyOn(lib,'methodName') 

但在情況下,我想窺探actualy構造函數,因此我已經試過:

spyOn(lib); 


it('lib should be instantiated for each matching element', function() { 
    spyOn(lib); 
    expect(lib.calls.count()).toEqual(2); 
}); 

不幸的是,這只是給了我一個在控制檯中的錯誤:

"Error: undefined() method does not exist in ..." 

我怎麼能窺探構造函數?

+2

嘗試使用'spyOn(window,'lib')' – javiyu 2014-09-05 15:06:14

+0

使用'lib.callCount' – inf3rno 2014-09-05 17:18:52

+0

可能重複[Jasmine - Spying on在構造函數中調用方法](http://stackoverflow.com/questions/8733978/jasmine-spying-on-a-method-call-within-a-constructor) – 2015-07-30 20:36:48

回答

11

spyOn()函數只能替換對象屬性,所以你唯一能做的就是窺探原型。現在,如果你要窺探真正的類的原型,它會干擾其他測試,所以你必須使用原型繼承。

你可以做這樣的事情:

var mockClass = function (Subject) { 
    var Surrogate = function() { 
     Surrogate.prototype.constructor.apply(this, arguments); 
    }; 
    Surrogate.prototype = Object.create(Subject.prototype); 
    Surrogate.prototype.constructor = Subject; 
    return Surrogate; 
}; 

一些測試:

var My = function (a) { 
    this.init(a); 
}; 
My.prototype = { 
    init: function (a) { 
     this.setA(a); 
    }, 
    setA: function (a) { 
     this.a = a; 
    } 
}; 

var Mock = mockClass(My); 
spyOn(Mock.prototype, "constructor").andCallThrough(); 
spyOn(Mock.prototype, "init"); 

var m = new Mock(1); 

expect(Mock.prototype.init).toBe(m.init); 
expect(My.prototype.init).not.toBe(m.init); 
expect(m.constructor).toHaveBeenCalledWith(1); 
expect(m.init).toHaveBeenCalledWith(1); 
expect(m.a).toBeUndefined(); 
m.setA(1); 
expect(m.a).toBe(1); 

spyOn(Mock.prototype, "setA").andCallFake(function (a) { 
    this.a = a + 1; 
}); 
m.setA(1); 
expect(m.setA).toHaveBeenCalledWith(1); 
expect(m.a).toBe(2); 

如果你的代碼使用x.constructor基於類型檢查不能在constructor間諜。但我認爲這隻能通過集成測試和設計糟糕的代碼來實現......

相關問題