最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

javascript - Cannot inject providers into Karma test - Stack Overflow

matteradmin5PV0评论

I'm trying to inject the $urlRouterProvider into my tests but I keep getting the unknown provider issue. I'm using ui.router and testing directives and need to be able to get access to these provider, or all the tests fail...

navbar.spec.js

'use strict';

describe('Directive: nav-bar', function () {

  beforeEach(module('ui.router'));
  beforeEach(module('ngMock'));
  beforeEach(module('kitchenapp'));


  var $httpBackend,
    $templateCache,
    $pile,
    $urlRouterProvider,
    $scope;

  beforeEach(inject(function (_$httpBackend_, _$templateCache_, _$pile_, _$urlRouterProvider_) {


    $httpBackend = _$httpBackend_;
    $templateCache = _$templateCache_;
    $pile = _$pile_;
    $urlRouterProvider = _$urlRouterProvider_;

    $urlRouterProvider.deferIntercept();

    $scope = $rootScope.$new();
    element = angular.element('<nav-bar></nav-bar>');
    element = $pile(element)(scope);
    $rootScope.$$phase || $rootScope.$apply();


  }));

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

  it('\'s brand link should be titled \'KitchenApp\' and should navigate to the root address when clicked', function () {

    expect(2).toEqual(2);

  });


});

Karma.conf.js

'use strict';

module.exports = function (config) {
  config.set({

    basePath: 'client',

    frameworks: ['jasmine'],

    preprocessors: {
      '**/*.html': ['ng-html2js']
    },

    ngHtml2JsPreprocessor: {
      stripPrefix: 'client/',
      moduleName: 'templates'
    },

    plugins: [
      'karma-phantomjs-launcher',
      'karma-jasmine',
      'karma-ng-html2js-preprocessor'
    ],

    files: [
      'bower_ponents/angular/angular.js',
      'bower_ponents/angular-ui-router/release/angular-ui-router.js',
      'bower_ponents/angular-mocks/angular-mocks.js',
      'bower_ponents/angular-bootstrap/ui-bootstrap-tpls.js',
      'bower_ponents/angular-ui-grid/ui-grid.js',
      'bower_ponents/angular-animate/angular-animate.js',
      'bower_ponents/angular-sanitize/angular-sanitize.js',
      'bower_ponents/angular-cookies/angular-cookies.js',
      'bower_ponents/angular-resource/angular-resource.js',
      'bower_ponents/angular-socket-io/socket.min.js',
      'bower_ponents/angular-touch/angular-touch.js',
      'bower_ponents/angular-bootstrap-calendar/dist/js/angular-bootstrap-calendar-tpls.js',
      'app.js',
      'views/**/*.js',
      'services/**/*.js',
      'directives/**/*.js',
      'directives/**/*.html'
    ],

    exclude: [
      'views/**/*.e2e.js',
      'services/socket/socket.service.js'
    ],

    reporters: ['progress'],

    port: 9876,

    colors: true,

    // possible values:
    // config.LOG_DISABLE
    // config.LOG_ERROR
    // config.LOG_WARN
    // config.LOG_INFO
    // config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    autoWatch: false,

    browsers: ['PhantomJS'],

    singleRun: true
  });
};

app.js

'use strict';

angular.module('kitchenapp', [
  //Native services
  'ngCookies',
  'ngResource',
  'ngSanitize',
  'ngAnimate',
  'ngTouch',

  //3rd party
  'btford.socket-io',
  'ui.router',
  'ui.grid',
  'mwl.calendar',
  'ui.bootstrap'
])
  .config(function ($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider, calendarConfigProvider) {

    $urlRouterProvider.otherwise('/');
    $locationProvider.html5Mode(true);
    $httpProvider.interceptors.push('authInterceptor');

    calendarConfigProvider.configureDateFormats({
      hour: 'HH:mm' //this will configure the hour view to display in 24 hour format rather than the default of 12 hour
    });

    calendarConfigProvider.configureTitleFormats({
      day: 'ddd D MMM' //this will configure the day view title to be shorter
    });

  })
  .factory('authInterceptor',
  function ($rootScope, $q, $cookieStore, $location) {
    return {

      request: function (config) {
        config.headers = config.headers || {};
        if ($cookieStore.get('token')) {
          config.headers.Authorization = 'Bearer ' + $cookieStore.get('token');
        }
        return config;
      },

      responseError: function (response) {
        if (response.status === 401) {
          $location.path('/login');
          $cookieStore.remove('token');
          return $q.reject(response);
        }
        else {
          return $q.reject(response);
        }
      }

    };
  })

  .run(function ($rootScope, $state, Auth) {

    $rootScope.Auth = Auth;
    //$rootScope.$on("$stateChangeError", console.log.bind(console));

  });

Error

Error: [$injector:unpr] Unknown provider: $urlRouterProviderProvider <- $urlRouterProvider
.3.15/$injector/unpr?p0=%24urlRouterProviderProvider%20%3C-%20%24urlRouterProvider
    at /Users/jamessherry/sites/kitchenappFull/client/bower_ponents/angular/angular.js:4015
    at getService (/Users/jamessherry/sites/kitchenappFull/client/bower_ponents/angular/angular.js:4162)
    at /Users/jamessherry/sites/kitchenappFull/client/bower_ponents/angular/angular.js:4020
    at getService (/Users/jamessherry/sites/kitchenappFull/client/bower_ponents/angular/angular.js:4162)
    at invoke (/Users/jamessherry/sites/kitchenappFull/client/bower_ponents/angular/angular.js:4194)
    at workFn (/Users/jamessherry/sites/kitchenappFull/client/bower_ponents/angular-mocks/angular-mocks.js:2436)
undefined
TypeError: 'undefined' is not an object (evaluating '$httpBackend.verifyNoOutstandingExpectation')
    at /Users/jamessherry/sites/kitchenappFull/client/directives/nav-bar/nav-bar.spec.js:34

Any help would be greatly appreciated...

EDIT The issue occurs as soon as the provider injection is requested in the inject arguments; I suspect that's why the $httpBackend is not present, as it crashes at that point...

I'm trying to inject the $urlRouterProvider into my tests but I keep getting the unknown provider issue. I'm using ui.router and testing directives and need to be able to get access to these provider, or all the tests fail...

navbar.spec.js

'use strict';

describe('Directive: nav-bar', function () {

  beforeEach(module('ui.router'));
  beforeEach(module('ngMock'));
  beforeEach(module('kitchenapp'));


  var $httpBackend,
    $templateCache,
    $pile,
    $urlRouterProvider,
    $scope;

  beforeEach(inject(function (_$httpBackend_, _$templateCache_, _$pile_, _$urlRouterProvider_) {


    $httpBackend = _$httpBackend_;
    $templateCache = _$templateCache_;
    $pile = _$pile_;
    $urlRouterProvider = _$urlRouterProvider_;

    $urlRouterProvider.deferIntercept();

    $scope = $rootScope.$new();
    element = angular.element('<nav-bar></nav-bar>');
    element = $pile(element)(scope);
    $rootScope.$$phase || $rootScope.$apply();


  }));

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

  it('\'s brand link should be titled \'KitchenApp\' and should navigate to the root address when clicked', function () {

    expect(2).toEqual(2);

  });


});

Karma.conf.js

'use strict';

module.exports = function (config) {
  config.set({

    basePath: 'client',

    frameworks: ['jasmine'],

    preprocessors: {
      '**/*.html': ['ng-html2js']
    },

    ngHtml2JsPreprocessor: {
      stripPrefix: 'client/',
      moduleName: 'templates'
    },

    plugins: [
      'karma-phantomjs-launcher',
      'karma-jasmine',
      'karma-ng-html2js-preprocessor'
    ],

    files: [
      'bower_ponents/angular/angular.js',
      'bower_ponents/angular-ui-router/release/angular-ui-router.js',
      'bower_ponents/angular-mocks/angular-mocks.js',
      'bower_ponents/angular-bootstrap/ui-bootstrap-tpls.js',
      'bower_ponents/angular-ui-grid/ui-grid.js',
      'bower_ponents/angular-animate/angular-animate.js',
      'bower_ponents/angular-sanitize/angular-sanitize.js',
      'bower_ponents/angular-cookies/angular-cookies.js',
      'bower_ponents/angular-resource/angular-resource.js',
      'bower_ponents/angular-socket-io/socket.min.js',
      'bower_ponents/angular-touch/angular-touch.js',
      'bower_ponents/angular-bootstrap-calendar/dist/js/angular-bootstrap-calendar-tpls.js',
      'app.js',
      'views/**/*.js',
      'services/**/*.js',
      'directives/**/*.js',
      'directives/**/*.html'
    ],

    exclude: [
      'views/**/*.e2e.js',
      'services/socket/socket.service.js'
    ],

    reporters: ['progress'],

    port: 9876,

    colors: true,

    // possible values:
    // config.LOG_DISABLE
    // config.LOG_ERROR
    // config.LOG_WARN
    // config.LOG_INFO
    // config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    autoWatch: false,

    browsers: ['PhantomJS'],

    singleRun: true
  });
};

app.js

'use strict';

angular.module('kitchenapp', [
  //Native services
  'ngCookies',
  'ngResource',
  'ngSanitize',
  'ngAnimate',
  'ngTouch',

  //3rd party
  'btford.socket-io',
  'ui.router',
  'ui.grid',
  'mwl.calendar',
  'ui.bootstrap'
])
  .config(function ($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider, calendarConfigProvider) {

    $urlRouterProvider.otherwise('/');
    $locationProvider.html5Mode(true);
    $httpProvider.interceptors.push('authInterceptor');

    calendarConfigProvider.configureDateFormats({
      hour: 'HH:mm' //this will configure the hour view to display in 24 hour format rather than the default of 12 hour
    });

    calendarConfigProvider.configureTitleFormats({
      day: 'ddd D MMM' //this will configure the day view title to be shorter
    });

  })
  .factory('authInterceptor',
  function ($rootScope, $q, $cookieStore, $location) {
    return {

      request: function (config) {
        config.headers = config.headers || {};
        if ($cookieStore.get('token')) {
          config.headers.Authorization = 'Bearer ' + $cookieStore.get('token');
        }
        return config;
      },

      responseError: function (response) {
        if (response.status === 401) {
          $location.path('/login');
          $cookieStore.remove('token');
          return $q.reject(response);
        }
        else {
          return $q.reject(response);
        }
      }

    };
  })

  .run(function ($rootScope, $state, Auth) {

    $rootScope.Auth = Auth;
    //$rootScope.$on("$stateChangeError", console.log.bind(console));

  });

Error

Error: [$injector:unpr] Unknown provider: $urlRouterProviderProvider <- $urlRouterProvider
http://errors.angularjs/1.3.15/$injector/unpr?p0=%24urlRouterProviderProvider%20%3C-%20%24urlRouterProvider
    at /Users/jamessherry/sites/kitchenappFull/client/bower_ponents/angular/angular.js:4015
    at getService (/Users/jamessherry/sites/kitchenappFull/client/bower_ponents/angular/angular.js:4162)
    at /Users/jamessherry/sites/kitchenappFull/client/bower_ponents/angular/angular.js:4020
    at getService (/Users/jamessherry/sites/kitchenappFull/client/bower_ponents/angular/angular.js:4162)
    at invoke (/Users/jamessherry/sites/kitchenappFull/client/bower_ponents/angular/angular.js:4194)
    at workFn (/Users/jamessherry/sites/kitchenappFull/client/bower_ponents/angular-mocks/angular-mocks.js:2436)
undefined
TypeError: 'undefined' is not an object (evaluating '$httpBackend.verifyNoOutstandingExpectation')
    at /Users/jamessherry/sites/kitchenappFull/client/directives/nav-bar/nav-bar.spec.js:34

Any help would be greatly appreciated...

EDIT The issue occurs as soon as the provider injection is requested in the inject arguments; I suspect that's why the $httpBackend is not present, as it crashes at that point...

Share Improve this question edited Apr 22, 2015 at 21:54 user1775718 asked Apr 22, 2015 at 21:44 user1775718user1775718 1,5782 gold badges19 silver badges35 bronze badges 2
  • have you tried moving angular mocks up in the karma files list? Perhaps it should be loaded before ui-router. – Davin Tryon Commented Apr 22, 2015 at 21:56
  • Hi @DavinTryon, I've tried playing around with the order but to no avail... :( – user1775718 Commented Apr 23, 2015 at 1:02
Add a ment  | 

2 Answers 2

Reset to default 3

So, it transpires that you can't inject '$urlRouterProvider' into a function and expect the $injector to find it. i.e. this won't work:

beforeEach(inject(function ($urlRouterProvider) {

Instead, you have to do it using module, like so:

beforeEach(module(function($urlRouterProvider) {
      console.log('in', $urlRouterProvider);
      $urlRouterProvider.deferIntercept();
    }));

Typescript version of this is:

beforeEach(this.module(function ($urlRouterProvider: angular.ui.IUrlRouterProvider) {
    $urlRouterProvider.deferIntercept(); 
}));

The "this." in front of moduleis required.

It also must e before any beforeEach(inject( lines.

Post a comment

comment list (0)

  1. No comments so far