Keith Paul Barrow
Keith Paul Barrow

Reputation: 328

Error: [$injector:unpr] Unknown provider - I think I've checked the obvious stuff

effectively in my unit test beforeEach I have

var moduleName = 'gameModel';
var providerName = 'gameConstants';
angular.module(moduleName);
inject(function($injector) {
    $injector.get(providerName);
});

I've copy-pasted the module name and the provider name in from the module and constant implementation itself, so I'm pretty sure it isn't a typo in the names. Karma is loading files in this order:

  1. angular
  2. angular-mocks
  3. The js file containing the module "gameModel" - which has no dependencies
  4. The js file containing the constant provider "gameConstants" - which has no dependencies
  5. The unit test file .js.

I think this covers the obvious stuff (thought I'm fairly new to angular) - the names seem to be OK and nothing should be trying to be injected before it should. But I'm still getting the unknown provider exception.

I've been on this a few hours and have discovered this weirdness I don't understand:

var moduleName = 'gameModel';
var providerName = 'gameConstants';
angular.module(moduleName);
inject(function($injector){
    console.log('Inject method, injector has provider: ', $injector.has(providerName));
    console.log('First provider name: ', angular.module(moduleName)._invokeQueue[0][2][0]);
});

var fooInjector =  angular.injector([moduleName]);
console.log('Explicitly rolled injector has provider: ', fooInjector.has(providerName));

via the inject method the has method returns false, but oddly I can get the provider name out from the module itself. If I roll my own injector (the code outside of the inject method) then has works and I can even get at the provider. Can anyone shed some light as to why it is happening - it seems to me like I'm somehow getting a different injector in for $inject and fooInjector

Upvotes: 0

Views: 819

Answers (1)

Shepless
Shepless

Reputation: 300

Short Answer

I believe your issue is that you are using angular.module instead of either just module or angular.mock.module.

Long Answer

The Angular mock library creates a mock module and inject function. It must do this as the non-mocked version of module and inject must still be able to function normally so you can actually run and test your Angular code.

Therefore when you are injecting the $injector service into the mock inject function, the mock library has no idea about the 'gameConstants' constant since you have not actually told the mock module about the 'gameModel' module.

Hope that helps.

Upvotes: 1

Related Questions