2013-12-21 19 views
1

我在網頁上有Jasmine,Knockout和jQuery。我已經寫了一些測試,我認爲它會驗證視圖模型以我期望的方式綁定到DOM,但jQuery似乎不能像我認爲的那樣模擬用戶交互:使用jquery測試knockout javascript頁面

例如,

<input type='text' id='someField' data-bind='value: someField'> 

<script> 

    var viewModel = { someField: ko.observable() }; 

    // ... 

    //this test passes 
    it('should update the DOM when I edit the model', function(){ 

     $('#someField').val('not the test value'); 

     viewModel.someField('test value'); 

     expect($('#someField').val()).toBe('test value'); 
    }); 

    //this test does not 
    it('should update the model when I change the DOM', function(){ 

     viewModel.someField('not the test value'); 

     $('#someField').val('test value'); 

     expect(viewModel.someField()).toBe('test value'); 
    }); 

</script> 

第一次測試通過,第二次測試失敗。當我實際上手動編輯某個字段時,視圖模型確實會改變;只有測試失敗,而不是它正在測試的行爲。當手動編輯頁面,視圖模型更新似乎發生「的onblur」,所以我改變了相關線路的測試:

$('#someField').val('test value').next('input').focus(); 

,但它仍然失敗。

我有類似的單選按鈕測試。當我手動點擊它們時,視圖模型確實會改變,但在測試中,調用$('#radioButton').click();不會更新視圖模型。

爲什麼Knockout不能識別jQuery對DOM的更改?

回答

2

您需要調用.change()才能讓knockout拿起該值以編程方式更改。

$('#someField').val('test value').change(); 

對於這項工作的jQuery必須包含/淘汰賽前裝!

這可能與事實有關,如果jQuery存在,Knockout.js將使用jQuery的抽象來處理事件,否則它將直接使用DOM Event API。 https://github.com/knockout/knockout/blob/master/src/utils.js(registerEventHandler和triggerEvent)

這應該可以在Knockout.js中修復。

+0

聽起來不錯,但我只是試了一下,什麼都沒有發生。 (我懷疑我試圖聚焦另一個元素是一種笨拙的做法,完全符合你的建議 - 你的方式更爲正確,但並不完全不同。)也許還有其他一些淘汰賽正在等待的事件呢? – Brad

+0

實際上,對文本輸入的「更改」被推遲,直到它失去焦點。儘管如此,即使將以下內容組合在一起:'$('#someField')。val('test value')。change()。blur();'不會改變測試...它仍然失敗。 – Brad

+0

我忘記了你還需要給予淘汰賽一段時間,在期待可觀察到之前做到這一點。 –