[英]How can I simulate a timeout event in a XHR using jasmine?
I'm testing a function that makes AJAX requests, allowing retries when the network is not working or there are timeouts because the connection is unstable (I'm thinking about mobile devices). 我正在测试一个发出AJAX请求的函数,允许在网络不工作时重试,或者由于连接不稳定而导致超时(我正在考虑移动设备)。
I'm sure it works because I've used it integrated with other code, but I want to have a proper test. 我确定它有效,因为我已将它与其他代码集成使用,但我希望进行适当的测试。
However I haven't been able to create a unit test to ensure it formally. 但是,我无法创建单元测试来正式确保它。 I'm using jasmine 2.3 along with karma and here is my code so far:
我正在使用茉莉花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();
}
}
And this is my test: 这是我的考验:
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
});
});
And this is the output of the test: 这是测试的输出:
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)
Use .responseTimeout
on a mocked request object, this method is provided by jasmine-ajax , but is not documented. 在
.responseTimeout
的请求对象上使用.responseTimeout
,此方法由jasmine-ajax提供 ,但未记录。
jasmine.Ajax.requests.mostRecent().responseTimeout();
But after that, calling .responseTimeout
on the first request, you still have an error, because the errorFn
callback fires only after several retries. 但是在那之后,在第一个请求上调用
.responseTimeout
,你仍然有一个错误,因为只有在几次重试后errorFn
触发errorFn
回调。 You have to deal with the next requests which are being sent automatically by request.ontimeout
defined in your code. 您必须处理由代码中定义的
request.ontimeout
自动发送的下一个请求。 It can be solved like that: 可以这样解决:
var retries = 3;
var request;
do {
request = jasmine.Ajax.requests.mostRecent();
request.responseTimeout();
retries -= 1;
} while(retries >= 0);
As a result, it will call a timeout
for each subsequent request. 结果,它将为每个后续请求调用
timeout
。
Here is some sandbox to play with the code http://plnkr.co/edit/vD2N66EwkpgiLFpg1Afc?p=preview 这里有一些沙盒可以使用代码http://plnkr.co/edit/vD2N66EwkpgiLFpg1Afc?p=preview
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.