Question

I'm trying to write a simple unit test for a controller in my app, but Jasmine is throwing an 'Unknown provider' error. It's choking on a provider that I wrote to help with retrieving template urls. The provider is injected into a config function so I can use it in routes.js.

The specific error I am getting is: Error: Unknown provider: assetPathProvider

Here is my Karma config:

files: [
  'vendor/assets/javascripts/jquery.js',
  'vendor/assets/javascripts/angular.js',
  'spec/javascripts/lib/angular/angular-mocks.js',
  'vendor/assets/javascripts/angular-*.js',
  'vendor/assets/javascripts/*.js',
  'app/assets/javascripts/initialize.js',
  'app/assets/javascripts/**/*.js',
  'spec/javascripts/unit/**/*.js'
],

I initialize my app like so:

Viewfinder = angular.module('viewfinder', [
  'ui.bootstrap',
  'scroll',
  'ngCookies',
  'ngResource',
  'chart',
  'http-auth-interceptor',
  'facebook-connect',
  'twitter-connect',
  'Alerts',
  'smartTable.table',
  'ngClipboard',
  'angularFileUpload'
])

Here is the top of routes.js

Viewfinder.config(['$routeProvider', '$locationProvider', 'assetPathProvider', function($routeProvider, $locationProvider, assetPathProvider) {

The provider is used in retrieving the correct template location in routes.js

...
templateUrl: assetPathProvider.get('welcome/signed_in.html'),
....

Here is the provider itself:

Viewfinder.provider('assetPath', [function() {
    this.get = function(path) {
    if(angular.isDefined(gon.config.manifest)) {
      return '/assets/' + gon.config.manifest[path]
    } else {
      return '/assets/' + path
    }
  }

  this.$get = function() {
    return {
      get: this.get
    }
  }
}]);

I've dumbed down my spec to be as simple as possible, but I can't get past the Unknown provider error.

Here is the spec:

describe('OneSheetPackagesViewController', function() {

  var $rootScope, $scope, $controller, message

  beforeEach(function() {
    module('viewfinder', function(assetPathProvider) {})
  })

  beforeEach(inject(function(_$rootScope_) {
    message = 'hello'
  }))

  it("should successfully submit a comment", function() {
    console.log(message)
    expect(message).toBeDefined()
  })
})

No correct solution

OTHER TIPS

Viewfinder.config(['$routeProvider', '$locationProvider', 'assetPathProvider', function($routeProvider, $locationProvider, assetPathProvider)

will be executed before

Viewfinder.provider('assetPath'

This when config is being executed assetPathProvider is not available. http://docs.angularjs.org/guide/module

Module Loading & Dependencies A module is a collection of configuration and run blocks which get applied to the application during the bootstrap process. In its simplest form the module consist of collection of two kinds of blocks:

Configuration blocks - get executed during the provider registrations and configuration phase. Only providers and constants can be injected into configuration blocks. This is to prevent accidental instantiation of services before they have been fully configured. Run blocks - get executed after the injector is created and are used to kickstart the application. Only instances and constants can be injected into run blocks. This is to prevent further system configuration during application run time.

Try writing the provider in another angular module and inject it as dependency to viewfinder. also remember to ensure that the file defining assetPath appears before the viewfinder in karma.conf

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top