qunit通过knockout viewmodel测试ajax

时间:2014-04-15 15:29:28

标签: ajax asynchronous knockout.js qunit

我有一个问题,使用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);
        */
});

0 个答案:

没有答案