How to test data polling on AngularJS with Jasmine? -


i have trouble test data polling in controller

controller logic looks this

$oninit() {   this.requestrootlocations();   this.startdatapolling(); }  private startdatapolling() {    this.stop = this.$interval(() =>     this.requestrootlocations()     , this.data_polling_interval); }  private requestrootlocations() {       this.locationsservice.requestrootelements().then(function (locationitem) {         ...          this.entitylist = (locationitem["locations"] instanceof array) ? locationitem["locations"] : [];       }.bind(this), function () {         console.log("error on loading locations data.");       });     } 

update: http request in service:

public requestrootelements() {       return this.$http.get(this.api + "locations").then((response) => response.data);     } 

this works fine expected.

the test case looks this

it("should call http request on intervals", function () {    ctrl.$oninit();   $httpbackend.whenget(api + "locations").respond(200, locationdata);    // advance in time 1 seconds   $interval.flush(1000);    $httpbackend.expectget(api + "locations");   // after 1 seconds locations should called once   $httpbackend.flush();    expect(ctrl.counts.length).tobe(4);   expect(ctrl.entities.length).tobe(6);    $interval.flush(datapollinginterval);   $httpbackend.expectget(api + "locations"); //does not work, why?   $httpbackend.flush();    // after second call data should same in case   expect(ctrl.counts.length).tobe(4);   expect(ctrl.entities.length).tobe(6); }); 

but on second expectget error

error: unsatisfied requests: /apiv1/locations

the problem here units aren't isolated. integration test (controller + service + $interval), not unit test. when test becomes red, it's not possible of units has failed.

the proper strategy unit-test mock tested unit (controller). $interval can optionally mocked too, , don't need test how works - tested angular.

constructor(...) {   ...   // bind callback method   this.datapollinghandler = this.datapollinghandler.bind(this); }  $oninit() {   this.requestrootlocations();   this.stop = this.$interval(this.datapollinghandler, this.data_polling_interval); }  private datapollinghandler() {   this.requestrootlocations() } 

and can tested like

spyon(ctrl, 'requestrootlocations');  // unbind callback method ctrl.datapollinghandler.call(null);  expect(ctrl.requestrootlocations).tohavebeencalled();  ...  var intervalpromise = $q.resolve(); var intervalmock = jasmine.createspy().and.returnvalue(intervalpromise); var ctrl = $controller(..., { $interval: intervalmock });  ctrl.$oninit(); expect(ctrl.stop).tobe(intervalpromise); expect($intervalstub).tohavebeencalledwith(ctrl.datapollinghandler, 1000);  ...  var locationsservicemock = {   requestrootlocations: jasmine.createspy().and.returnvalue($q.resolve(locationdata)); }  var ctrl = $controller(..., { locationsservice: locationsservicemock }); // ctrl.requestrootlocations can tested ... 

it ok have both unit , integration tests in suite, when proper controller , service unit tests exist, integration test becomes redundant.


Comments

Popular posts from this blog

Command prompt result in label. Python 2.7 -

javascript - How do I use URL parameters to change link href on page? -

amazon web services - AWS Route53 Trying To Get Site To Resolve To www -