不能将提供者注入Karma测试

时间:2015-04-22 21:44:19

标签: javascript angularjs karma-runner

我试图将$ 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

非常感谢任何帮助......

修改 一旦在inject参数中请求提供者注入,就会出现问题;我怀疑为什么$ httpBackend不存在,因为它在那时崩溃了......

2 个答案:

答案 0 :(得分:3)

因此,发现您不能将'$ urlRouterProvider'注入函数并期望$ injector找到它。即这不起作用:

beforeEach(inject(function ($urlRouterProvider) {

相反,你必须使用模块来完成它,如下所示:

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

答案 1 :(得分:0)

这是打字稿版本:

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

this.前面的“module”是必需的。

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