2011-12-12 49 views
3

我在使用jQuery $。當處理ajax回調函數時,我使用mockjax來模擬單元測試中的各種響應。其中一個響應返回500我的失敗回調的狀態錯誤引發錯誤,並在Q-單位我試圖用捕捉的錯誤「引發」但所有我得到的是實際的錯誤。Unit Test ajax failure with Q-Unit

下面是代碼:

var bar = new Object(); 
// ajax call, returns a promise object 
bar.ajaxCall = function() { 
    return $.ajax({ 
     url: "foo/foo" 
     , dataType: "json" 
     , data: { "blah": "blee" }  
    }); 
} 

// function I'm testing ... 
bar.handleAjax = function() { 
    return $.when(ajaxCall.call(this)) 
     .done(function(data) { /* Success callback */ }) 
     .fail(throw "Error!!"; }); 
} 

單元測試:

// Mock ajax call in the unit test 
var mock = $.mockjax({ 
    url: "foo/foo" 
    , contentType: "json" 
    , status: 500 
}); 

// unit test for "load" 
loadTest = function() { 
    test("testing load failure", function() { 
     stop(); // stop the test so QUnit knows to wait for the ajax response 
     raises(function() { 
     var promise = bar.handleAjax(); 
     }, "We expect an error to be thrown"); 
     setTimeout(function() { 
     start(); 
     }, 500); 
    }); 
} 

我怎麼可以重寫測試,以確保handleAjax是在適當的時候拋出一個錯誤?

回答

1

問題是raises()內部調用handleAjax()會立即返回,錯誤將拋出此函數。

爲了解決這個問題,你可以讓Ajax調用同步和這樣的埃羅將裏面raises()被拋出。

raises(function() { 
    $.ajaxSetup({ async: false }); 
    bar.handleAjax(); 
}, "We expect an error to be thrown"); 

HERE是工作代碼。

你的問題是你在fail()裏面拋出一個錯誤,你不能輕易控制這個失敗的回調何時被調用,除非你同步執行它,否則拋出異常。你可以重寫你的代碼,而不是拋出一個錯誤,你會調用一個回調函數。

bar.handleAjax = function(success, error) { 
    return $.when(this.ajaxCall.call(this)) 
    .done(function() { success && success.call(this); }) 
    .fail(function() { error && error.call(this); }); 
}; 

HERE是示例。

期待更好的想法:)。

+0

非常感謝@dzejkej。有沒有任何理由不讓所有的ajax在單元測試中同步運行?這似乎是因爲你不會有每當你不得不等待發生的操作設置超時它會更容易編寫測試。儘管這也不能幫助你檢測競爭條件。 第二種解決方案適用於我,我認爲以這種方式拋出錯誤更清晰。 – stinkycheeseman

+1

@stinkycheeseman:我沒有在測試中同步運行ajax的問題​​,因爲它使事情變得更容易實現。但是有些人在看到'async:false'和'$ .ajax'組合時自動生氣:P。我沒有看到任何其他解決方案,而不更改'bar'實現。 – kubetz