Dan Tao
Dan Tao

Reputation: 128327

How do I use $httpBackend to test only one HTTP request per test?

Say I have a controller which upon initialization makes 3 different requests with the $http service. I would like to write three different tests, each of which only cares about one of the requests.

For example, suppose the controller looks like:

app.controller('ExampleCtrl', function($scope, $http) {
  $http.get('/foo', /* ... */);
  $http.get('/bar', /* ... */);
  $http.get('/baz', /* ... */);
});

Then I would like to write tests like:

describe('ExampleCtrl', function() {
  var http;

  beforeEach(inject(function($httpBackend, $controller) {
    http = $httpBackend;
    $controller('ExampleCtrl');
  }));

  it('loads "/foo" and does whatever', function() {
    http.expectGET('/foo').repond(/* ... */);
    http.flush();
    expect(/* ... */);
  });

  it('loads "/bar" and does whatever else', function() {
    /* etc. */
  });
});

This doesn't appear to work because, from what I can see, when I call flush() Angular assumes I must have specified all of the requests that should have been made. So for instance if I only specified expectGET('/foo') then Angular will complain that there were unexpected requests to '/bar' and '/baz'.

Is there a way to do what I'm trying to do here? Am I approaching this problem from the wrong angle?

One approach, I realize, is that I could probably put all of the expectGETs in a beforeEach and only test the results in test cases. But that seems like an unfortunate workaround, having to scatter my expectations across multiple places.

Upvotes: 1

Views: 211

Answers (1)

Sylvain
Sylvain

Reputation: 19249

I think http.expectGET('/foo').repond(/* ... */); can be viewed as setup code. After all your are configuring a mock by telling it how to respond. So I'd put it in beforeEach and wouldn't see that as a workaroud.

Another option would be to mock $http with your own spy/mock using $provide:

beforeEach(module('plunker', function ($provide) {

  $provide.value('$http', {
    get : function(a){
      this.calls = this.calls || [];
      this.calls.push(a);
    }
  });

}));

And then you can check the calls the way you want to. See this plnkr to get you started.

Upvotes: 2

Related Questions