0

I was looking at this answer: https://stackoverflow.com/a/26992327/16584 and was trying to understand why the config section is needed.

angular.module('httpReal', ['ng'])
    .config(['$provide', function($provide) {
        $provide.decorator('$httpBackend', function() {
            return angular.injector(['ng']).get('$httpBackend');
        });
    }])
    .service('httpReal', ['$rootScope', function($rootScope) {
        this.submit = function() {
            $rootScope.$digest();
        };
    }]);

It doesn't seem to work for me without it, but I don't actually understand why it would be needed since we are never replacing httpBackend in the first place?

Community
  • 1
  • 1
Hortitude
  • 13,638
  • 16
  • 58
  • 72

1 Answers1

1

The context for angular.module('httpReal', ['ng'])... is the app that has ngMockE2E module loaded. The module overrides $httpBackend service with mocked implementation. Once the service is overridden, there's no way for $injector to get the original service.

angular.injector(['ng']).get('$httpBackend')

is supposed to return an instance of original $httpBackend service.

And decorator guarantees that mocked $httpBackend will be replaced with original implementation in lazy but solid manner. The service won't be instantiated if it isn't used. And decorated service doesn't depend on service loading order and can be overridden only by another decorator.

Since Angular 1.4 the whole config thing can be replaced by decorator method.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • I'm not using ngMockE2E as I'm running unit tests. And I can't see where this module overrides httpBackend needing it to be replaced. – Hortitude Jul 08 '16 at 00:02
  • Then it is `ngMock` in your case that overrides `$httpBackend`. If you have `angular-mocks` loaded and run unit test with suppored framework (Jasmine or Mocha), `ngMock` module is already loaded there, whether you want it or not. – Estus Flask Jul 08 '16 at 00:09
  • That makes sense except I don't quite understand where httpBackend gets swapped out for the "real one"? It seems like it's "restoring" the mock backend without having replaced it in the first place – Hortitude Jul 08 '16 at 18:36
  • `$httpBackend` mock [is defined by `ngMock` module](https://github.com/angular/angular.js/blob/v1.5.7/src/ngMock/angular-mocks.js#L2305). And `ngMock` [is loaded automatically in each spec when `inject(...)` is called](https://github.com/angular/angular.js/blob/v1.5.7/src/ngMock/angular-mocks.js#L3048). Otherwise `$http` would do real, async requests in unit tests, which is less than desirable in 99% of cases. Actually, it is 100%, because it becomes an integration test with real XHR request. – Estus Flask Jul 08 '16 at 18:50