2014-01-10 54 views
1

我對Jasmine和Marionette非常陌生,正在尋找一些關於如何測試的幫助,甚至只是考慮測試我的應用程序的正確方法。任何指針都是受歡迎的。Backbone,Marionette,Jasmine:如何測試jQuery延期事件

我有一個木偶控制器,我用來獲取我的模型,實例化我的視圖並呈現它們。我使用本頁底部的方法,以便在渲染視圖之前提取模型:https://github.com/marionettejs/backbone.marionette/blob/master/upgradeGuide.md#marionetteasync-is-no-longer-supported

我控制器的方法來獲取模型和顯示視圖看起來像這樣:

showCaseById: function(id){ 
    App.models.Case = new caseModel({ id: id }); 

    var promise = App.models.Case.fetch(); 
    $.when(promise).then(_.bind(this.showContentView, this)); 
}, 

正如你可以看到,它調用showContentView後的模型被取出。該方法在這裏:

showContentView: function(model){ 
    App.views.Body = new bodyView({ 
    model: App.models.Case 
    }); 

    App.views.Body.on('case:update', this.submitCase, this); 

    // this.layout is defined in the controller's initialize function 
    this.layout.content.show(App.views.Body); 
}, 

什麼是測試此功能的正確方法?我想在promise完成後測試showContentView函數的調用。我應該如何分解這個規格?

謝謝。

回答

0

首先,在你的showContentView方法的間諜,並斷言它被稱爲:

it('showCaseById', function (done) { 
    var controller = new Controller(); 
    spyOn(controller, 'showContentView'); 

    controller.showCaseById('foo'); 
    expect(controller.showContentView).toHaveBeenCalledWith(jasmine.any(caseModel)); 
}); 

其次,我建議你踩滅調用取(),所以你不打的網絡,但它的開始變得有點毛毛現在:

function caseModel() { 
    this.fetch = function() { 
     // return a promise here that resolves to a known value, e.g. 'blah' 
    }; 
} 

現在,你可以有一個略強斷言,但是這是一個有點shonky因爲你與你的依賴的內部擺弄周圍:

expect(controller.showContentView).toHaveBeenCalledWith('blah'); 

通過重寫caseModel,當你的控制器的方法去創建一個,它得到你的新版本而不是舊的,你可以控制新只是爲了本次測試的實施。

有很多方法可以使這段代碼更具可測試性,但是因爲您似乎剛開始進行測試,所以我不會深入其中。當你做更多的測試時,你一定會爲自己找出那些東西。

0

首先,瞭解_.bind(fn, context)實際上並沒有調用fn是很重要的。相反,它返回一個函數,當被調用時將調用fn()context定義了fn將在內部使用的對象this

這不是必要的,但你可以寫showCaseById爲:

showCaseById: function(id){ 
    App.models.Case = new caseModel({ id: id }); 

    var promise = App.models.Case.fetch(); 
    var fn = _.bind(this.showContentView, this); 
    $.when(promise).then(fn); 
}, 

正如我說的,這是不必要的,但現在你明白_.bind()返回功能和$.when(promise).then(...)接受一個函數作爲其(第一)的說法。

要回答實際問題,您可以通過添加另一個$.when(promise).then(...)聲明並附帶您自己選擇的測試功能來確認App.models.Case.fetch()承諾已完成。

showCaseById: function(id){ 
    App.models.Case = new caseModel({ id: id }); 

    var promise = App.models.Case.fetch(); 
    $.when(promise).then(_.bind(this.showContentView, this)); 

    // start: test 
    $.when(promise).then(function() { 
    console.log("caseModel " + id + " is ready");//or alert() if preferred 
    }); 
    // fin: test 
}, 

第二個$.when(promise).then(...)不會干擾第一個;相反,這兩個將順序執行。 console.log() satatement將提供可靠的確認,this.showContentView已被成功調用,並且初始渲染應該已經發生。

如果此時或之後沒有呈現任何內容,則您必須懷疑需要調試this.showContentView

相關問題