我有一个问题,使用qunit来测试一个knockout viewmodel函数,该函数本身调用async(ajax)例程。我理解asyncTest的使用,但它似乎并不合适。通常情况下,这会引导我进入模型的重构,但我喜欢它现在的工作方式(正确或错误!)。该方案概述如下。
问题是我不想/需要测试ajax功能本身。 ' loadDesks'是viewmodel的公共函数,因此,我真正想要测试的单元。但是,这没有回调,因此我无法指示qunit在完成时调用start(),因为没有回调测试例程。
因此,在下面的代码中,测试失败,因为async ajax调用在异步调用完成之前返回qunit并填充了observable数组 - 正如预期的那样。然而,在测试中评论等待任意数量的时间是非常脆弱的。这个模式在某个地方显然是错误的,但我很难看到,有人可以帮忙吗?
显然,使这个调用同步修复了它,但是我必须在真正的调用中这样做才能使它在模拟上生效,并且这是不可接受的。
视图模型
deskns.viewmodel = (function () {
var
desks = ko.observableArray(),
loadDesks = function () {
deskns.Ajax.loadDesks(reloadDeskArray, ajaxErrorHandler);
},
reloadDeskArray = function (data) {
desks.removeAll();
for (var i = 0; i < data.length; i++) {
addRow(data[i]);
}
},
addRow = function (data) {
desks.push(new deskns.Desk({
id: data.id,
name: data.name,
description: data.description,
isActive: data.isActive,
activeUserCount: data.userCount
}));
}
};
return {
desks: desks,
loadDesks : loadDesks
};
})();
Ajax js文件
deskns.Ajax = (function() {
var
callback = function (func, data) {
if (typeof (func) == 'function') {
func(data);
}
},
loadDesks = function (successFunc, errorFunc) {
$.ajax({
url: '/Desk/List',
success: function (data) { callback(successFunc, data); },
error: function (data) { callback(errorFunc, data); }
});
};
return {
loadDesks: loadDesks
}
})();
测试并模拟
$.mockjax({
url: '/Desk/List',
contentType: "text/json",
responseText: JSON.stringify([{ id: '1', name: 'testname', description: 'testdescr', isActive: true, activeUserCount: 1 }])
});
test("listing desks displays items", function () {
vm.loadDesks();
deepEqual(vm.desks().length, 1, 'desk length is one when one user is loaded');
/* Here comes the hack
setTimeout(function() {
start();
deepEqual(vm.desks().length, 1, 'desk length is one when one user is loaded');
}, 500);
*/
});