如何有效地测试延迟总是

How to efficiently test deferred always

本文关键字:延迟 测试 有效地      更新时间:2023-09-26

在用jQuery编写测试代码时,ajax(或get)总是部分地甚至是在bluebird承诺中最终像这样:

function doStuff() {
    console.log('stuff done');
}
function someFunction() {
    return $.get('someurl').always(doStuff);
}

我发现自己总是这样写(QUnit)测试:

QUnit.test("doStuff will be called when someFunction succeeds", function (assert) {
    var deferred = $.Deferred();
    var backup = $.get;
    $.get = function () { return deferred; };
    var doStuffIsCalled = false;
    doStuff = function(){ doStuffIsCalled = true; };
    deferred.resolve({});
    return someFunction().then(function(){
        $.get = backup;
        assert.ok(doStuffIsCalled);
    });
});
QUnit.test("doStuff will be called when someFunction fails", function (assert) {
    var deferred = $.Deferred();
    var backup = $.get;
    $.get = function () { return deferred; };
    var doStuffIsCalled = false;
    doStuff = function(){ doStuffIsCalled = true; };
    deferred.reject(new Error('some error'));
    return someFunction().catch(function(){
        $.get = backup;
        assert.ok(doStuffIsCalled);
    });
});

可以工作,但是有点冗长。是否有一些更有效的方法,最好是在单个测试中,直接测试在延迟的always部分调用的代码?

您可以使用Sinon.js模拟jQuery ajax(或get)以及一般的承诺。

一种方法是:

function someFunction() {
    return $.get('/mytest').always(doStuff);
}
function givenFncExecutesAndServerRespondsWith(reponseNumber, contentType, response) {
    server.respondWith("GET", "/mytest", [reponseNumber, contentType, response]);
    someFunction();
    server.respond();
}
module("Testing server responses", {
    setup: function () {
        server = sinon.sandbox.useFakeServer();
        doStuff = sinon.spy();
    },
    teardown: function () {
        server.restore();
    }
});
test("doStuff will be called when someFunction succeeds", function () {
    givenFncExecutesAndServerRespondsWith(200, '', '');
    ok(doStuff.called, "spy called once");
});
test("doStuff will be called when someFunction fails", function () {
    givenFncExecutesAndServerRespondsWith(500, '', '');
    ok(doStuff.called, "spy called once");
});

您可以在此小提琴中使用此代码。如果您使用donefail来调用回调,而不是always,则相应的测试将失败。

对代码的解释如下:

  1. 创建一个假服务器和一个间谍将作为always回调。
  2. 根据我们正在测试的内容修改服务器响应的响应数。

希望能有所帮助。