无法将提供者注入 Karma 测试

Cannot inject providers into Karma test

我正在尝试将 $urlRouterProvider 注入到我的测试中,但我一直遇到未知提供程序问题。我正在使用 ui.router 和测试指令,需要能够访问这些提供程序,否则所有测试都会失败...

navbar.spec.js

'use strict';

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

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


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

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


    $httpBackend = _$httpBackend_;
    $templateCache = _$templateCache_;
    $compile = _$compile_;
    $urlRouterProvider = _$urlRouterProvider_;

    $urlRouterProvider.deferIntercept();

    $scope = $rootScope.$new();
    element = angular.element('<nav-bar></nav-bar>');
    element = $compile(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_components/angular/angular.js',
      'bower_components/angular-ui-router/release/angular-ui-router.js',
      'bower_components/angular-mocks/angular-mocks.js',
      'bower_components/angular-bootstrap/ui-bootstrap-tpls.js',
      'bower_components/angular-ui-grid/ui-grid.js',
      'bower_components/angular-animate/angular-animate.js',
      'bower_components/angular-sanitize/angular-sanitize.js',
      'bower_components/angular-cookies/angular-cookies.js',
      'bower_components/angular-resource/angular-resource.js',
      'bower_components/angular-socket-io/socket.min.js',
      'bower_components/angular-touch/angular-touch.js',
      'bower_components/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: [$injector:unpr] Unknown provider: $urlRouterProviderProvider <- $urlRouterProvider
http://errors.angularjs.org/1.3.15/$injector/unpr?p0=%24urlRouterProviderProvider%20%3C-%20%24urlRouterProvider
    at /Users/jamessherry/sites/kitchenappFull/client/bower_components/angular/angular.js:4015
    at getService (/Users/jamessherry/sites/kitchenappFull/client/bower_components/angular/angular.js:4162)
    at /Users/jamessherry/sites/kitchenappFull/client/bower_components/angular/angular.js:4020
    at getService (/Users/jamessherry/sites/kitchenappFull/client/bower_components/angular/angular.js:4162)
    at invoke (/Users/jamessherry/sites/kitchenappFull/client/bower_components/angular/angular.js:4194)
    at workFn (/Users/jamessherry/sites/kitchenappFull/client/bower_components/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

任何帮助将不胜感激...

编辑 一旦在注入参数中请求提供程序注入,就会出现此问题;我怀疑这就是 $httpBackend 不存在的原因,因为它在那时崩溃了...

因此,事实证明您不能将“$urlRouterProvider”注入函数并期望 $injector 找到它。也就是说,这行不通:

beforeEach(inject(function ($urlRouterProvider) {

相反,您必须使用模块来执行此操作,如下所示:

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

这个的打字稿版本是:

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

module前面的“this.”为必填项

它也必须在任何 beforeEach(inject( 行之前。