我正在尝试为我的淘汰视图模型编写一些qunit单元测试,我遇到了一个有趣的问题。
在我的视图模型中,我有以下功能:
Get = function (id) {
return $.ajax({
url: API + "/" + id,
type: 'GET',
dataType: 'json',
timeout: Timeout,
statusCode: {
200: GetOneSuccess,
404: ItemNotFound
},
error: function () {
//Item(null);
}
});
},
然后在我的单元测试中我有这个:
vm.Get(vm.Item().Id()).then(function () {
ok(false, "Failure!");
},function () {
equal(vm.Item(), null, "Item was removed");
start();
});
ItemNotFound如下:
ItemNotFound = function () {
Item(null);
}
这非常简单,如果API控制器返回“NotFound(错误404)”,则将Item设置为null。我发现我的测试失败了,因为当“then”被称为ItemNotFound函数时还没有完成。
如果我在单元测试中添加超时,则可以:
vm.Get(vm.Item().Id()).then(function () {
ok(false, "Failure!");
},function () {
setTimeout(function () {
equal(vm.Item(), null, "Item was removed");
start();
}, 2000);
});
有人有什么想法吗?我应该不打扰statusCodes并只处理错误处理程序中的所有错误类型?看起来不那么优雅。
答案 0 :(得分:0)
在触发状态代码函数之前,首先触发错误处理程序。 “then”函数采用“成功回调”和“错误回调”。所以从本质上讲,你的错误(失败)是在状态代码“notfound”触发之前触发的。
当您设置超时时,该函数会立即返回,触发您的状态代码,然后根据您设置的超时,触发该特定代码。
如果您仍然需要代码结构,那么我就是这样做的。您的GET函数应该返回一个Deffered promise对象,该对象封装了实际的ajax调用,并且没有指定成功或错误处理程序,并首先从statusCode调用您的成功或错误函数。
我为同一个
创造了一个小提琴http://jsfiddle.net/sujesharukil/BWA9D/15/
var data = {
json: $.toJSON({
text: 'some text',
array: [1, 2, 'three'],
object: {
par1: 'another text',
par2: [3, 2, 'one'],
par3: {}
}
})
}
var callEcho = function(url) {
return $.Deferred(function(def){
$.ajax({
url: url,
type: "POST",
data: data,
statusCode: {
200: function(data,xhr){
GetOneSuccess();
def.resolve(data);
},
404: function(xhr){
ItemNotFound();
def.reject();
}
}
});
}).promise();
};
function GetOneSuccess(){
alert('Get One success Called');
}
function ItemNotFound(){
alert('Item Not Found Called');
}
var testFunc = function(url){
var js = callEcho(url);
js.done(function(data){
alert(JSON.stringify(data) + ' done function called');
});
js.fail(function(){
alert('fail function called.');
});
}
//fire the success
testFunc("/echo/json/" );
//fire the fail
testFunc("/echo/jso/");