如何使用Sinon/QUnit模拟“超时”或“失败”的响应?

28

我成功完成了模拟成功状态的排序,但是在使用SinonQunit测试ajax函数时似乎无法理解如何模拟失败/超时条件:

我的设置如下:

$(document).ready( function() {

    module( "myTests", {
        setup: function() {
            xhr = sinon.sandbox.useFakeXMLHttpRequest();
            xhr.requests = [];
            xhr.onCreate = function (request) {
                xhr.requests.push(request);
            };

            myObj = new MyObj("#elemSelector");
        },
        teardown: function() {
            myObj.destroy();
            xhr.restore();
        }
    });
});

我的成功案例测试是这样的,愉快地运行并将接收到的数据传递给成功方法:

test("The data fetch method reacts correctly to receiving data",
    function () {
        sinon.spy(MyObject.prototype, "ajaxSuccess");

        MyObject.prototype.fetchData();

        //check a call got heard
        equal(1, xhr.requests.length);

        //return a success method for that obj
        xhr.requests[0].respond(200, {
                "Content-Type": "application/json"
            },
            '[{ "responseData": "some test data" }]'
        );
        //check the correct success method was called
        ok(MyObj.prototype.ajaxSuccess.calledOnce);

        MyObj.prototype.ajaxSuccess.restore();
    }
);

然而,我无法确定我应该将什么放在这里代替它:

xhr.requests[0].respond(200, { "Content-Type": "application/json" },
                '[{ "responseData": "some test data" }]');

如何使我的ajax调用处理程序监听失败或超时方法?我唯一能想到尝试的事情是这样的:

xhr.requests[0].respond(408);

但它不起作用。

我做错了什么或者我有什么误解?非常感谢所有的帮助 :)


超时是指在给定的时间内没有响应,因此您无法返回超时。 - Danubian Sailor
1
我希望sinon能够克服这个问题,并为所有类型的响应提供标准化的接口。如果我无法使用sinon“返回”超时,那么我该如何伪造一个超时呢? - Caroline
我不了解sinon,所以可能有一些特定的东西,但通常你将超时设置为1毫秒,并在服务器端或模拟服务器端使用wait。 - Danubian Sailor
好主意 - 我会尝试在超时方法中使用它,但是对于失败方法,sinon 的标准方式是什么? - Caroline
4个回答

1
对于超时,sinon的模拟定时器可以帮助。使用它们,您不需要将超时设置为1毫秒。至于失败,您的方法看起来正确。您能给我们更多代码,特别是失败处理程序吗?

0

做类似这样的事情

requests[0].respond(
        404,
        {
            'Content-Type': 'text/plain',
            'Content-Length': 14
        },
        'File not found'
);

作用是触发jQuery AJAX请求中的“error”回调。

至于超时,您可以像下面这样使用Sinon的模拟时钟:

test('timeout-test', function() {
    var clock = sinon.useFakeTimers();
    var errorCallback = sinon.spy();

    jQuery.ajax({
        url: '/foobar.php',
        data: 'some data',
        error: errorCallback,
        timeout: 20000 // 20 seconds
    });

    // Advance 19 seconds in time
    clock.tick(19000);

    strictEqual(errorCallback.callCount, 0, 'error callback was not called before timeout');

    // Advance another 2 seconds in time
    clock.tick(2000);

    strictEqual(errorCallback.callCount, 1, 'error callback was called once after timeout');
});

1
或许使用jQuery的Ajax是一种方法,但CJ正在询问sinon的伪造XHR;这两种方法都对sinon无效。 - Yuri Gadow

0
我会使用的主要思路是将与请求相关的所有内容都包装在“另一个函数”中,该函数返回一个Promise。
然后在测试中,当我模拟“另一个函数”时,我只需返回一个Promise.reject({})。
如果某个端点将给我超时,那就相当于一个失败的Promise。

-1

在您的 $.ajax() 调用上设置超时,并使用 Sinon fake timers 在响应之前将时钟向前移动。


CJ并没有使用$.ajax()调用,而是使用sinon模拟XHR调用,而sinon不支持.timeout属性。 - Yuri Gadow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接