如何有效地测试 deferred always
How to efficiently test deferred always
在 jQuery ajax(或获取)always part or even in bluebird promises finally 中编写代码测试时,如下所示:
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);
});
});
这可行,但有些冗长。有没有更有效的方法,最好是在单个测试中,直接测试在延迟的始终部分调用的代码?
您可以使用 Sinon.js 模拟 jQuery ajax(或获取)以及一般的承诺。
一种方法可以是:
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");
});
您可以在此 fiddle 中使用此代码。如果您使用 done
或 fail
而不是 always
来调用回调,则相应的测试将失败。
代码解释如下:
- 创建一个假服务器和一个将充当
always
回调的间谍。
- 根据我们正在测试的内容修改服务器响应的响应编号。
希望对您有所帮助。
在 jQuery ajax(或获取)always part or even in bluebird promises finally 中编写代码测试时,如下所示:
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);
});
});
这可行,但有些冗长。有没有更有效的方法,最好是在单个测试中,直接测试在延迟的始终部分调用的代码?
您可以使用 Sinon.js 模拟 jQuery ajax(或获取)以及一般的承诺。
一种方法可以是:
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");
});
您可以在此 fiddle 中使用此代码。如果您使用 done
或 fail
而不是 always
来调用回调,则相应的测试将失败。
代码解释如下:
- 创建一个假服务器和一个将充当
always
回调的间谍。 - 根据我们正在测试的内容修改服务器响应的响应编号。
希望对您有所帮助。