2011-11-11 59 views
4

我正在使用Jasmine編寫我的測試,但我想我會遇到任何其他測試框架的這個問題。比方說,我們有一個模塊foo有兩個功能,BarBaz,這是構造函數(但可能只是正常功能):嘲笑模塊外部的Node.js模塊中的構造函數(或其他函數)

var Bar = exports.Bar = function Bar() { 
    this.baz = new Baz(); 
}; 

var Baz = exports.Baz = function Baz() { 

}; 

現在我想考Bar,而是用假Baz實現:

var foo = require('foo'); 

describe("foo.Bar", function() { 
    it("initializes its own Baz", function() { 
    spyOn(foo, 'Baz'); // this replaces foo.Baz with a fake implementation 
    var bar = new foo.Bar(); 
    expect(foo.Baz).toHaveBeenCalled(); 
    }); 
}); 

的問題是,此測試將失敗,因爲Bar使用可變Baz,其不能從外部變更實例化新的Baz。通過使用spyOn()交換的唯一東西是exports.Baz

明顯的解決辦法是寫this.baz = new exports.Baz();,但它有點尷尬。如果我想在模塊中使用更多功能,則必須始終使用前綴exports.來呼叫所有功能。這裏有沒有其他的方法?

+0

試試'spyOn(window,'Baz');'和'expect(window.Baz).toHaveBeenCalled();'。 – Prusse

+0

@Prusse,我猜Node沒有'window'對象。 –

+0

對不起,但是如果有全局對象,你可以使用它。 – Prusse

回答

1

如果你能以某種方式分離這兩個類,就像允許其他實現Baz類給bar一樣,那麼我認爲這是最好的方法,你應該去做。


但如果你真的希望能夠能夠參考exports.BazBaz,再有就是,我能想到的,使用with的一種方式。

據說使用with通常是一種不好的做法,應該避免,我不會在我自己的代碼中使用它,但這是解決這個問題的一種方法,甚至可以是a legimate use,只要你知道你在做什麼。

這裏有雲:

with(exports) { 

    exports.Bar = function Bar() { 
     console.log('this is bar!'); 
     this.baz = new Baz(); 
    }; 

    exports.Baz = function Baz() { 
     console.log('original baz!'); 
    }; 

} 

在另一個模塊,如果你改變foo.Baz別的東西,裏面Baz富也會仰望它。

我仍然會推薦找到一種方法讓這兩個類彼此獨立,然後你可以給Bar提供任何你想要的Baz的實現。

+0

使用'with'很有趣,但我覺得太冒昧。我寧願不去解耦這兩個「類」,因爲'Baz'永遠不會在'Bar'之外實例化。你可以說,也許我不應該測試'Baz',因爲它是一個內部的實現細節,但實際上整個系統的行爲非常複雜,我需要更細粒度的測試。無論如何感謝提示。 –

相關問題