7

I have an AngularJS service which performs an $http GET request and caches the response locally. It is designed to handle the multiple calls happening simultaneously, such that only the data from the final call is cached.

Specifically, if the following happens:

  • Request A Started
  • Request B Started
  • Request B Completed
  • Request A Completed

The result is that the response of request B is cached, because it was initiated last.

However I'm having trouble unit testing this in Jasmine.

I can set-up two $httpBackend.expectGET() expectations, but I can only flush them in the order they are requested.

Essentially I need to be able to so something like this:

$httpBackend.expectGET('/one').respond(200, data1);
$httpBackend.expectGET('/two').respond(200, data2);

myService.doSomething('/one');
myService.doSomething('/two');

$httpBackend.flush('/two');
$httpBackend.flush('/one');

expect(myService.data).toBe(data2);

Can anyone suggest a neat way to achieve this?

James Thurley
  • 2,650
  • 26
  • 38
  • Maybe you can play with the count property https://docs.angularjs.org/api/ngMock/service/$httpBackend#flush but I don't think it will be enough – Boris Charpentier Feb 04 '15 at 10:21
  • Unfortunately the documentation specifically says about the count property that it specifies the "Number of responses to flush (in the order they arrived)". I suspect I'll need to do something clever with spies to change the behaviour of $http or $httpBackend in some way. – James Thurley Feb 04 '15 at 10:25

1 Answers1

2

I ended up solving this by extracting out the HTTP calls into simple stubs. That allowed me to remove $http from the service and $httpBackend from the unit tests, and instead mock the stubs to return promises that I could resolve in any order.

James Thurley
  • 2,650
  • 26
  • 38