mardi 13 septembre 2016

Unit testing Angular HTTP interceptor

I have a standard HTTP interceptor as a factory:

angular
  .module('app.services')
  .factory('HttpInterceptorService', HttpInterceptorService);

function HttpInterceptorService($injector) {

  // Callable functions
  var service = {
    response: response,
    responseError: responseError
  };

  return service;

  // Pass through clean response
  function response(data) {
    return data;
  }

  // Handle error response
  function responseError(rejection, $state) {

    // Handle bypass requests
    if (rejection.config.bypassInterceptor) {
      return rejection;
    }

    // Get $state via $injector to avoid a circular dependency
    var state = $injector.get('$state');

    switch (rejection.status) {
      case 404:
        return state.go('404');
        break;
      default:
        return state.go('error');
    }
  }

}

In manual testing, I can see this works correctly by redirecting the user to the relevant 404 or error page if an HTTP call returns an error response. The basic principal of this is documented by Angular here: http://ift.tt/1iD2D7J$http#interceptors

Now I'm trying to write a unit test with Karma & Jasmine to test that the responseError function works correctly. I've checked out this SO answer to help me. My test looks like this:

describe('HttpInterceptorService', function() {

  // Bindable members
  var $window,
      HttpInterceptorService;

  // Load module
  beforeEach(module('app.services'));

  // Set window value
  beforeEach(function () {
    $window = { location: { href: null } };

    module(function($provide) {
      $provide.value('$window', $window);
    });
  });

  // Bind references to global variables
  beforeEach(inject(function(_HttpInterceptorService_) {
    HttpInterceptorService = _HttpInterceptorService_;
  }));

  // Check service exists with methods
  it('Exists with required methods', function() {
    expect(HttpInterceptorService).toBeDefined();
    expect(angular.isFunction(HttpInterceptorService.response)).toBe(true);
    expect(angular.isFunction(HttpInterceptorService.responseError)).toBe(true);
  });

  // Test 404 HTTP response
  describe('When HTTP response 404', function () {
    beforeEach(function() {
      HttpInterceptorService.responseError({ status: 404 });
    });

    it('Sets window location', function () {
      expect($window.location.href).toBe('/404');
    });
  });

});

My test passes the Exists with required methods check but fails Sets window location with the following error:

TypeError: undefined is not an object (evaluating 'rejection.config.bypassInterceptor') in ...

Aucun commentaire:

Enregistrer un commentaire