【问题标题】:Multiple responses from identical calls in asynch QUnit + Mockjax tests在异步 QUnit + Mockjax 测试中来自相同调用的多个响应
【发布时间】:2012-08-28 18:55:33
【问题描述】:

我正在尝试使用 QUnit 和 Mockjax 测试一些 jQuery ajax 代码,并让它为不同的测试返回不同的 JSON,like this:

$(document).ready(function() {

function functionToTest() {
    return $.getJSON('/echo/json/', {
        json: JSON.stringify({
            "won't": "run"
        })
    });
}

module("first");

test("first test", function() {

    stop();

    $.mockjax({
        url: '/echo/json/',
        responseText: JSON.stringify({
            hello: 'HEYO!'
        })
    });

    functionToTest().done(function(json) {
        ok(true, json.hello);
        start();
    });               
});


 test("second test", function() {

    stop();

    $.mockjax({
        url: '/echo/json/',
        responseText: JSON.stringify({
            hello: 'HELL NO!'
        })
    });


    functionToTest().done(function(json) {
        ok(true, json.hello);
        start();
    });


});

});

不幸的是,它每次调用都返回相同的响应,并且无法保证顺序,所以想知道如何设置它以便与实际请求耦合并出现with this

$.mockjax({
    url: '/echo/json/',
    response: function(settings) {

        if (JSON.parse(settings.data.json).order === 1) {
            this.responseText = JSON.stringify({
                hello: 'HEYO!'
            });
        } else {
            this.responseText = JSON.stringify({
                hello: 'HELL NO!'
            });
        }
    }
});

这依赖于发送到服务器的参数,但是没有参数的请求呢,我仍然需要测试不同的响应?有没有办法使用 QUnit 的 setup/teardown 来做到这一点?

【问题讨论】:

    标签: jquery ajax asynchronous qunit mockjax


    【解决方案1】:

    您似乎需要在创建另一个模拟处理程序之前调用 $.mockjaxClear();

    Mockjax 通过更改 $.ajax 方法来工作。

    its source code 的底部,我们可以看到您正在使用的 $.mockjax 方法,这是它的公开方法之一,它只是将更多处理程序附加到 mockHandlers 数组。

        $.mockjax = function(settings) {
            var i = mockHandlers.length;
            mockHandlers[i] = settings;
            return i;
        };
    

    在 $.ajax 替换的源代码中,我们可以看到:

        // Iterate over our mock handlers (in registration order) until we find
        // one that is willing to intercept the request
        for(var k = 0; k < mockHandlers.length; k++) {
    

    您的问题是由于 /echo/json/ url 数组中的第一个处理程序(因此不是最新的)模拟处理程序满足 $.ajax 方法。

    这里是my fork of your fiddle,只需添加一个$.mockjaxClear() 行。


    编辑:

    更灵活的解决方案:

    • 在任何测试函数之外,删除一个变量,该变量将具有请求处理程序的 ID 以供以后更改。
    • 在需要覆盖某个处理程序的模块之前,声明一个变量(不需要初始值)以保存要修改的处理程序的备份。
    • 然后在模块设置功能中使用 $.extend 将设置从 $.mockjax.handler(&lt;your handlerID variable&gt;) 复制到此备份。在模块的拆解中,使用 $.mockjaxClear(&lt;your handlerID variable&gt;) 删除模块,然后将 &lt;your handlerID variable&gt; 设置为其他值。
    • 现在您可以覆盖模块 setup 和各个测试函数中的处理程序。

    但不要相信我的话。 Check out the fiddle.

    这样就灵活多了。您可以更改该处理程序并保留您可能拥有的所有其他处理程序。

    它似乎确实容易出错,所以我建议要小心。

    【讨论】:

    • 单元测试不会说谎!我本可以发誓我以前尝试过 mockjaxClear ......我将不得不再次开始服药:P
    • 我在模块中拆掉了它,事实上,即使按 ID 清除单个项目对我来说似乎也失败了。测试体中的 Clear all 不太灵活,但可以工作。
    • 宁愿将赏金奖励给能够灵活地为模块声明一组默认值的东西,除非我确信我需要的是糟糕的代码气味。
    • @SimonGibbs 我想一个好方法是将模拟设置对象声明为变量,并在模块设置和拆卸中更改它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-14
    • 2017-11-03
    • 1970-01-01
    • 2015-03-21
    • 1970-01-01
    相关资源
    最近更新 更多