Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

injector already created. can not register a module

I am a new bee to Angular JS and was trying to make something out of it in a proper TDD way, but while testing i am getting this error:

Injector already created, can not register a module!

This is the service i am talking about.

bookCatalogApp.service('authorService', ["$resource", "$q", function($resource, $q){

    var Author =$resource('/book-catalog/author/all',{},{
        getAll : { method: 'GET', isArray: true}
    });

    var authorService = {};

    authorService.assignAuthors = function(data){
        authorService.allAuthors = data;
    };

    authorService.getAll = function(){
        if (authorService.allAuthors)
            return {then: function(callback){callback(authorService.allAuthors)}}

        var deferred = $q.defer();
        Author.getAll(function(data){
            deferred.resolve(data);
            authorService.assignAuthors(data);
        });
        return deferred.promise;
    };

    return authorService;
}]);

This is the test for the above service

describe("Author Book Service",function(){
    var authorService;
    beforeEach(module("bookCatalogApp"));
    beforeEach(inject(function($injector) {
        authorService = $injector.get('authorService');
    }));

    afterEach(function() {
        httpBackend.verifyNoOutstandingExpectation();
        httpBackend.verifyNoOutstandingRequest();
    });

    describe("#getAll", function() {
        it('should get all the authors for the first time', function() {
            var authors = [{id:1 , name:'Prayas'}, {id:2 , name:'Prateek'}];

            httpBackend.when('GET', '/book-catalog/author/all').respond(200, authors);

            var promise = authorService.getAll();

            httpBackend.flush();
            promise.then(function(data){
                expect(data.length).toBe(2)
            });
        });

        it('should get all the authors as they have already cached', function() {
            authorService.allAuthors = [{id:1 , name:'Prayas'}, {id:2 , name:'Prateek'}];

            var promise = authorService.getAll();

            promise.then(function(data){
                expect(data.length).toBe(2)
            });
        });

    });
})

Any help will be appreciated.

like image 232
Prateek Jain Avatar asked Jul 23 '14 00:07

Prateek Jain


3 Answers

If you are mixing calls to module('someApp') and inject($someDependency) you will get this error.

All your calls to module('someApp') must occur before your calls to inject($someDependency).

like image 56
zayquan Avatar answered Nov 19 '22 15:11

zayquan


You're using the inject function wrong. As the documentation states, the inject function already instantiates a new instance of $injector. My guess is that by passing $injector as a argument to the inject function you are asking it to instantiate the $injector service twice.

Just use inject to pass in the service you want to check. Underneath the covers, inject will use the $injector service it instantiates to grab services.

You can fix this problem by changing the second beforeEach statement to:

beforeEach(inject(function(_authorService_) {
    authorService = _authorService_;
}));

One other thing to note. The argument authorService passed to the inject function has been wrapped with '_' so it's name does not hide the variable created within the describe function. Thats also documented in the inject documentation.

like image 40
loyalBrown Avatar answered Nov 19 '22 16:11

loyalBrown


Not sure that this is the cause, but your beforeEach should be like this:

beforeEach(function() {
  inject(function($injector) {
    authorService = $injector.get('authorService');
  }
});
like image 1
gilamran Avatar answered Nov 19 '22 16:11

gilamran