我正在测试一个发出 AJAX 请求的功能,允许在网络不工作或因连接不稳定而超时时重试(我正在考虑移动设备)。
我确信它可以工作,因为我已经将它与其他代码集成使用,但我想进行适当的测试。
但是我还没有能够创建一个单元测试来正式地确保它。我正在使用 jasmine 2.3 和 karma,这是我目前的代码:
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)
最佳答案
在模拟请求对象上使用 .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
关于javascript - 如何使用 jasmine 在 XHR 中模拟超时事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30256322/