我正在测试一个发出AJAX请求的函数,允许在网络不工作时重试,或者由于连接不稳定而导致超时(我正在考虑移动设备)。
我确信它有效,因为我已将它与其他代码集成使用,但我希望进行适当的测试。
但是,我无法创建单元测试以确保正式。我正在使用茉莉花2.3和业力,到目前为止这是我的代码:
var RETRIES=2;
var TIMEOUT=1000;
function doRequest(method, url, successFn, errorFn, body, retries) {
var request = new XMLHttpRequest();
retries = retries === undefined ? RETRIES : retries;
request.open(method, url);
request.setRequestHeader('Accept', 'application/json');
request.setRequestHeader('Content-Type', 'application/json');
request.onload = function () {
if (request.status < 300 && request.status >= 200) {
successFn(JSON.parse(request.responseText));
} else {
if (errorFn) {
errorFn(this.status, this.responseText);
}
}
};
request.onerror = function () {
if (this.readyState === 4 && this.status === 0) {
//there is no connection
errorFn('NO_NETWORK');
} else {
errorFn(this.status, this.responseText);
}
};
if (retries > 0) {
request.ontimeout = function () {
doRequest(method, url, successFn, errorFn, body, retries - 1);
};
} else {
request.ontimeout = function () {
errorFn('timeout');
};
}
request.timeout = TIMEOUT;
if (body) {
request.send(body);
} else {
request.send();
}
}
这是我的考验:
describe('Ajax request', function () {
'use strict';
var RETRIES=2;
var TIMEOUT=1000;
beforeEach(function () {
jasmine.Ajax.install();
jasmine.clock().install();
});
afterEach(function () {
jasmine.Ajax.uninstall();
jasmine.clock().uninstall();
});
it(' should call error callback function when a tiemout happens', function () {
var doneFn = jasmine.createSpy('onLoad');
var errorFn=jasmine.createSpy('onTimeout');
doRequest('GET','http://www.mockedaddress.com', doneFn, errorFn,null,RETRIES);
var request = jasmine.Ajax.requests.mostRecent();
expect(request.method).toBe('GET');
jasmine.clock().tick(TIMEOUT*(RETRIES+1)+50); //first attempt and then 2 retries
expect(errorFn).toHaveBeenCalled(); // assertion failed
});
});
这是测试的结果:
Expected spy onTimeout to have been called.
at Object.<anonymous> (js/test/doRequest_test.js:75:0)
Chrome 42.0.2311 (Windows 7): Executed 1 of 1 (1 FAILED) ERROR (0.007 secs / 0.008 secs)
答案 0 :(得分:3)
在模拟的请求对象上使用.responseTimeout
,此方法由 jasmine-ajax 提供,但未记录。
jasmine.Ajax.requests.mostRecent().responseTimeout();
但在此之后,在第一个请求上调用.responseTimeout
时,仍然会出现错误,因为errorFn
回调仅在多次重试后才会触发。您必须处理代码中定义的request.ontimeout
自动发送的下一个请求。它可以这样解决:
var retries = 3;
var request;
do {
request = jasmine.Ajax.requests.mostRecent();
request.responseTimeout();
retries -= 1;
} while(retries >= 0);
因此,它会为每个后续请求调用timeout
。
以下是一些使用代码http://plnkr.co/edit/vD2N66EwkpgiLFpg1Afc?p=preview
的沙箱