(AngularJS) Testing headers with whenGET / expectGET

Jotting this down here in case anyone else stumbles on the same issue(s) in AngularJS.

Suppose you’re mocking out $httpBackend in a unit test and want to test headers, like so:

// Assume $httpBackend and $http have been properly injected above
it('should not send a token if none is set', function() {
 $httpBackend.whenGET('/api-call', function(headers) {
   expect(headers.Authorization).toBeUndefined();
 }).respond(200, {hello: 'world'});
 $http.get('/api-call');
 $httpBackend.flush();
});

This won’t work. If a function is passed to whenGET, it expects a true/false return value to signal whether the headers were correct. Instead, try this:

// Assume $httpBackend and $http have been properly injected above
it('should not send a token if none is set', function() {
 $httpBackend.whenGET('/api-call', function(headers) {
   return !headers.Authorization;
 }).respond(200, {hello: 'world'});
 $http.get('/api-call');
 $httpBackend.flush();
});

Now, however, when the header test fails, you’ll get the following error:

Error: Unexpected request: GET /api-call

This is a bit misleading, since it implies the $http call somehow never hit $httpbackend. However, the issue isn’t that the GET request was unexpected; it’s that the the GET request with that particular header was incorrect. If you swap whenGET with expectGET, you’ll get a much more sensible failure message:

 Error: Expected GET /api-call with different headers

In both cases, returning the correct header should make this failure go away.

4 Replies to “(AngularJS) Testing headers with whenGET / expectGET”

  1. Hi, I am trying to test if a request has a specific header. From your suggestions, the expectation differs from actual call in that the actual one has ‘headers’ object, but here I am looking for function. The following is a snippet from my test.

    var loginUrl = 'https://www.someurl.com/login';

    $httpBackend
    .expect('POST', loginUrl,
    someData, function (headers) {
    return !headers['content-type']; // checking for this header's presence
    })
    .respond();

    // some function call -> which makes $http request

    $httpBackend.flush(); // flushing the request

    // expect a promise object.

    This fails. Can you help me out..

    1. The header name might just be case sensitive. That is, try: headers['Content-Type'].

      Alternatively, Angular (or something else) may be altering the header name somehow. You might get some useful info from console.log(headers).

  2. Hi, my code is as follows.

    it(‘should get data[Friendly names] from fake server’, inject(function ($http) {

    $httpBackend.expectGET(‘phones/phones.json’).
    respond(200, { hello: ‘world’ });

    $http.get(‘phones/phones.json’).success(function (data) {
    $scope.phones = data;
    });
    }));

    But the it never returns hello world text, I mean the response. Please let me know what I am missing.

    1. Use following

      it(‘should get data[Friendly names] from fake server’, inject(function ($httpBackend, $http, $scope) {
      $httpBackend.whenGET(‘phones/phones.json’). respond(201, { hello: ‘world’ });
      $http.get(‘phones/phones.json’).success(function (data) {
      $scope.phones = data;
      });
      $httpBackend.flush();//important

      }))

Leave a Reply

Your email address will not be published.