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

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -