Understanding injection dependency in app and tests in AngularJS

Jscti

I have a dependency injection (understanding) problem while testing a directive (AjaxLoader displayed only when there is a pending request).

App declaration :

angular.module('app', [
    'directives.ajaxLoader',
    'services.httpRequestTracker',
    [...]
])

Directive code :

angular.module('directives.ajaxLoader', [])
.directive('ajaxLoader', ['httpRequestTracker',
    function(httpRequestTracker) {
        return {
            templateUrl: 'common/ajaxLoader.tpl.html',
            link: function($scope) { // This function can have more parameters after $scope, $element, $attrs, $controller
                $scope.hasPendingRequests = function() {
                    return httpRequestTracker.hasPendingRequests();
                };
            }
        };
    }
])

Test code :

describe('ajaxLoader', function() {

    beforeEach(function() {
        module('directives.ajaxLoader', 'common/ajaxLoader.tpl.html');
    });

    describe('ajaxLoader directive', function() {});
});

From there, my directive works perfectly well in the browser, but tests fails with an error like :

Error: [$injector:unpr] Unknown provider: httpRequestTrackerProvider <- httpRequestTracker <- ajaxLoaderDirective

Ok, so I need to inject my dependency somewhere. I have two solutions :

  • in my directive directly :
angular.module('directives.ajaxLoader', [
     'services.httpRequestTracker'
])
  • in my test code directly :
beforeEach(function() {
     module('directives.ajaxLoader', 'common/ajaxLoader.tpl.html', 'services.httpRequestTracker');
});

Both works, but I don't understand which one is the better and why ? And why is it working in my browser from the start and fails in my test ? In both case, all my directives and trackers are injected in my main app declaration

Thanks

Eduard Gamonal

Loading modules

It works in your application because services.httpRequestTracker is loaded. you did that by declaring it as a dependency of the main app module (your first code snippet).

However, when you test things, you want to mock everything that is not being tested to avoid biass. In your case, what if you had a problem in services.httpRequestTracker? ajaxLoader might be fine but your tests will fail.

Mocking

To mock everything else, you have two options:

To use a dependency, you have to load the module with module().

you will have to load the dependency, but this might have a mock implementation.

Dependency Injection

Dependency injection lets you decouple classes. There is a service locator to resolve dependencies by name. That is, you say attribute a of class C is of type 'animal' (a string!). The service locator in the angular core finds which component implements it. A way of determining this is by looking up the loaded modules (e.g. dependencies of the main app module).

You didn't define any of this in your testing area (but it isn't a problem!). Karma uses a file karma.conf that contains a list of files to use. You might use this file to add libraries or mocked components.

With your particular problem:

The directive depends on httpRequestTracker. If you don't inject it there, it won't work (so it's ok). In your test, you have to load both. That's why the first time it failed and the second it worked. However, instead of loading httpRequestTracker, I'd load a mock implementation of it.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Dependency injection and Tests

From Dev

AngularJS Dependency Injection

From Dev

AngularJS - dependency injection

From Dev

Order of AngularJS dependency injection

From Dev

AngularJS : Dependency injection ngResource

From Dev

Understanding Inversion of Control and Dependency Injection

From Dev

Understanding Inversion of Control and Dependency Injection

From Dev

Is automatic dependency injection available in AngularJS?

From Dev

AngularJS Dependency Injection where to specify?

From Dev

Angularjs custom filter and dependency injection

From Dev

AngularJS name collision in Dependency Injection?

From Dev

angularjs 1.5 component dependency injection

From Dev

dependency injection into decorator functions in angularJS

From Dev

Reverse Engineering AngularJS dependency Injection

From Dev

Angularjs custom filter and dependency injection

From Dev

Dependency Injection of functions with Factories (AngularJS)

From Dev

Angularjs dependency injection inside factory

From Dev

AngularJS - is there any dependency injection container?

From Dev

Dependency injection and inversion of control in AngularJS

From Dev

Android App Architecture and Dependency injection

From Dev

Better understanding of Dependency Injection - Resolving New Instances?

From Dev

Understanding Angular2 Dependency Injection in modules

From Dev

Mocking Service dependency in angularjs tests

From Dev

AngularJS module app dependency

From Dev

Understanding AngularJS App Routing

From Dev

Best practice for dependency injection in an AngularJS service with TypeScript

From Dev

Confused about AngularJS dependency injection inconsistency

From Dev

Turn off implicit dependency injection in AngularJS

From Dev

AngularJS - Dependency injection involving asynchronous data

Related Related

  1. 1

    Dependency injection and Tests

  2. 2

    AngularJS Dependency Injection

  3. 3

    AngularJS - dependency injection

  4. 4

    Order of AngularJS dependency injection

  5. 5

    AngularJS : Dependency injection ngResource

  6. 6

    Understanding Inversion of Control and Dependency Injection

  7. 7

    Understanding Inversion of Control and Dependency Injection

  8. 8

    Is automatic dependency injection available in AngularJS?

  9. 9

    AngularJS Dependency Injection where to specify?

  10. 10

    Angularjs custom filter and dependency injection

  11. 11

    AngularJS name collision in Dependency Injection?

  12. 12

    angularjs 1.5 component dependency injection

  13. 13

    dependency injection into decorator functions in angularJS

  14. 14

    Reverse Engineering AngularJS dependency Injection

  15. 15

    Angularjs custom filter and dependency injection

  16. 16

    Dependency Injection of functions with Factories (AngularJS)

  17. 17

    Angularjs dependency injection inside factory

  18. 18

    AngularJS - is there any dependency injection container?

  19. 19

    Dependency injection and inversion of control in AngularJS

  20. 20

    Android App Architecture and Dependency injection

  21. 21

    Better understanding of Dependency Injection - Resolving New Instances?

  22. 22

    Understanding Angular2 Dependency Injection in modules

  23. 23

    Mocking Service dependency in angularjs tests

  24. 24

    AngularJS module app dependency

  25. 25

    Understanding AngularJS App Routing

  26. 26

    Best practice for dependency injection in an AngularJS service with TypeScript

  27. 27

    Confused about AngularJS dependency injection inconsistency

  28. 28

    Turn off implicit dependency injection in AngularJS

  29. 29

    AngularJS - Dependency injection involving asynchronous data

HotTag

Archive