Skip to content

Please document AngularAMD.inject #3

@tylercollier

Description

@tylercollier

Thanks for AngularAMD and also this example project with Karma. Without it I never could have figured things out. Even so, it took me quite a while, and as the point of this project is to help others and serve as an example, I think it would be helpful if you document/describe AngularAMD.inject in the README.

I have a test that looks like this:

define ['app', 'angularAMD', 'proof_ctrl', 'angular-mocks'], (app, angularAMD, ProofCtrl) ->
  $controller = null
  scope = null
  beforeEach ->
    module 'app'
      inject (_$rootScope_, _$controller_) ->
      scope = _$rootScope_.$new()
      $controller = _$controller_ 'ProofOfConceptCtrl',
        $scope: scope
  it 'can see ProofCtrl', ->
    $scope = {}
    expect($controller.myvalue).to.equal 777

I am seeing the following error:

PhantomJS 1.9.8 (Linux 0.0.0)  "after each" hook FAILED
    Error: [$injector:unpr] http://errors.angularjs.org/1.3.17/$injector/unpr?p0=%24rootElementProvider%20%3C-%20%24rootElement
        at /home/tylercollier/repos/reaper/vendor/assets/bower_components/angular/angular.min.js:38
        at d (/home/tylercollier/repos/reaper/vendor/assets/bower_components/angular/angular.min.js:36)
        at /home/tylercollier/repos/reaper/vendor/assets/bower_components/angular/angular.min.js:38
        at d (/home/tylercollier/repos/reaper/vendor/assets/bower_components/angular/angular.min.js:36)
        at /home/tylercollier/repos/reaper/vendor/assets/bower_components/angular-mocks/angular-mocks.js:2246

Unfortunately, it's a race condition because it only happens some of the time. Perhaps half?

The fix came when I looked at this project VERY carefully and noticed your use of AngularAMD.inject, which would go in my code above on line 6 (instead of just inject by itself). This completely eradicates the problem.

For others, until it gets documented by someone in the know (Marcos), I'll mention what I know.

In the AngularAMD.js source code, there is this:

/**
 * Create inject function that uses cached $injector.
 * Designed primarly to be used during unit testing.
 */
AngularAMD.prototype.inject = function () {
    checkBootstrapped();
    return run_injector.invoke.apply(null, arguments);
};

You can see that its job is to throw an error if bootstrapping hasn't taken place. And then it uses Angular's injector from app.run(['$injector']... to do dependency injection.

Honestly, I'm not sure why it doesn't throw the error "angularAMD not initialized". If you run this project, you'll see the following output:

$ karma start test/karma.conf.js 
INFO [karma]: Karma v0.12.37 server started at http://localhost:2080/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.8 (Linux 0.0.0)]: Connected on socket dYjOSEd1olGnXAhEuzQX with id 5815923
PhantomJS 1.9.8 (Linux 0.0.0) LOG: '### Running app_test.js: '

PhantomJS 1.9.8 (Linux 0.0.0) LOG: '### Running home-controller_test.js'

PhantomJS 1.9.8 (Linux 0.0.0) LOG: '### Running simple_directive_test.js'

PhantomJS 1.9.8 (Linux 0.0.0) LOG: '### Running page1_controller_test.js'

LOG: '### angularAMD bootstrapped.'
PhantomJS 1.9.8 (Linux 0.0.0): Executed 7 of 7 SUCCESS (1.012 secs / 1.011 secs)

Note how it says "angularAMD bootstrapped" last! It's the same thing in my own project. It's confusing. But it works. But I'd like to know how/why. Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions