概括地說,我同意戴夫牛頓的答案在上面。但是,您應該考慮這種方法的一些邊緣情況。
徑的變化以Dave的溶液,與另一種測試情況:
// 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);
});
});
第二次測試將因爲在第一測試間諜設置橫跨測試邊界持續到第二個方法失敗; called_method不會增加call_count,所以this.call_count不等於1.也可以想出帶有誤報的場景 - 測試通過,不應該。因爲間諜依然存在,創建的Klass實例越多,間諜將消耗的內存堆越大,因爲間諜會將每次調用記錄到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;
});
[注 - 一個小意見,完成一種更好的解決辦法是改變你編寫的生產代碼,以使代碼更易於測試的方式。通常,對原型進行窺探可能是一種可以避免的代碼嗅覺。而不是在構造函數中實例化依賴項,注入它們。而不是在構造函數中進行初始化,請遵循適當的init方法。
謝謝你。最好的描述,我已經看到了這一主題的一整天 – Subimage 2012-06-03 02:00:46
有一個預感,有一個合法的解決方案,在那裏。謝謝。 – BradGreens 2013-10-10 22:17:23
這種方法有兩個問題。首先,它會導致內存泄漏 - 即將調用Klass的所有將來實例的called_method方法,並且隨着更多調用的進行,間諜的內存消耗將會增加。其次,更重要的是,這也可能導致多次測試,詢問克拉斯互相交流,因爲間諜已經被調用。您應該確保刪除間諜或將Klass.prototype.called_method重置爲測試用例末尾的原始方法。 – alecmce 2013-11-19 01:49:53