javascript - How can I simulate a timeout event in a XHR using jasmine? -
i'm testing function makes ajax requests, allowing retries when network not working or there timeouts because connection unstable (i'm thinking mobile devices).
i'm sure works because i've used integrated other code, want have proper test.
however haven't been able create unit test ensure formally. i'm using jasmine 2.3 along karma , here code far:
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 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 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 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 , 2 retries expect(errorfn).tohavebeencalled(); // assertion failed }); });
and output of test:
expected spy ontimeout have been called. @ 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 mocked request object, method provided jasmine-ajax, not documented.
jasmine.ajax.requests.mostrecent().responsetimeout();
but after that, calling .responsetimeout
on first request, still have error, because errorfn
callback fires after several retries. have deal next requests being sent automatically request.ontimeout
defined in code. can solved that:
var retries = 3; var request; { request = jasmine.ajax.requests.mostrecent(); request.responsetimeout(); retries -= 1; } while(retries >= 0);
as result, call timeout
each subsequent request.
here sandbox play code http://plnkr.co/edit/vd2n66ewkpgilfpg1afc?p=preview
Comments
Post a Comment