2012-11-20 54 views
6

我感興趣的是如何在全球範圍內模擬在瀏覽器中的。具體來說,我最感興趣的是在Firefox這樣做,但寧願一個通用的解決方案。如何模擬瀏覽器中的文件選取器進行單元測試?

我只關心防止文件選取器對話框出現。我不需要能夠斷言它確實開放。問題是我有用於打開文件選擇器的JavaScript代碼的單元測試。當對話框打開時,暫停測試套件的執行。

一個示例情況是我正在測試Backbone.ViewonRender方法。該方法呈現子視圖,它將在呈現時打開文件選取器。由於我不是直接測試該子視圖,因此當我僅對單元測試onRender方法的某些其他部分感興趣時,我不想嘲笑其部分行爲。

例子:

//Test file 
it("should do something", function() { 
    var view = new App.Views.SomeView(); 
    spyOn(view.modelBinder, "bind"); 
    view.render(); 
    expect(view.modelBinder.bind).toHaveBeenCalled(); 
}); 

//View file 
onRender : function() { 
    this.modelBinder.bind(this.el, this.model); 
    this.$("#thing").html(this.subview.render().el); //This line has a side effect that opens file picker 
} 

從本質上講,我不想明確地模擬出導致要打開的文件選擇器,因爲它不是我的興趣在這裏測試的行爲。這樣做會使測試套件變得更加脆弱並且難以維護。

+0

使用是否使用js-test-driver? – leeand00

+0

幫我一個忙,並添加單元測試並註釋顯示它的函數被調用的行。 – leeand00

+0

增加了一些代碼和情況說明。 –

回答

0

使用sinon來模擬/間諜/存根電話。您可以測試正在進行的呼叫,而不是實際進行呼叫。

通過這種方式,您可以測試該函數已被調用,而無需調用顯示該對話框的實際函數。

+0

我不希望這樣做,因爲它隨整個套件而變化,導致文件選擇器打開。我寧願能夠在全球範圍內防止選擇器打開。 –

+0

在上面添加了一些解釋,說明爲什麼我不想刪除導致文件選取器打開的特定方法/事件。 –

+0

@AndrewHubbs如果您的單元測試依賴於您正在編寫的API以外的其他API,那麼您正在進行單元測試錯誤,然後它變成集成測試而不是單元測試。 – leeand00

0

回答你的問題:只是不。

我會用空函數替換subview.render()以避免不希望的副作用。但是你說:

「我不想明確嘲笑出導致要打開 文件選擇器的行爲,因爲它是不是我感興趣的測試 ...」

這有點矛盾。如果你想單元測試App.Views.SomeView,你不得不嘲笑外部合作者,特別是時,不感興趣,幷包括您的文件選擇器。另一方面,當你進行單元測試時,你不應該混淆SUT

嘲諷實際上將讓你的測試更易紅,但要確保你的產品代碼沒有從耦合的患病形式(恕我直言,與Backbone.js的應用程序的一個常見缺陷遭受的唯一途徑。 )

您需要避免文件選擇器顯示的唯一地方是單元測試您的文件選取器本身,在這種情況下,您可以使用sinon作爲擁塞或者如果您使用jQuery。請記住「永不嘲笑你不擁有的類型」規則。

相關問題