【问题标题】:Can't get tests to work in presence of third-party module无法在存在第三方模块的情况下进行测试
【发布时间】:2014-12-02 08:41:25
【问题描述】:

我有一个 AngularJS 控制器测试,它工作得很好,直到我添加了某个模块。这是我得到的错误:

TypeError: 'undefined' 不是函数(评估 'this.handlePostMessage.bind(this)')

有问题的模块是ng-token-auth。这是我的应用程序的配置文件:

'use strict';

/**
 * @ngdoc overview
 * @name lunchHubApp
 * @description
 * # lunchHubApp
 *
 * Main module of the application.
 */
var app = angular.module('lunchHubApp', [
  'ngAnimate',
  'ngCookies',
  'ngResource',
  'ngRoute',
  'ngSanitize',
  'ngTouch',
  'rails',
  'ng-token-auth' // <------------ IT WORKS WITHOUT THIS
]);

app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
  $locationProvider.html5Mode(true);
  $routeProvider
    .when('/', {
      templateUrl: 'views/main.html',
      controller: 'MainCtrl'
    })
    .when('/today', {
      templateUrl: 'views/announcements.html',
      controller: 'AnnouncementsCtrl',
      resolve: {
        auth: ['$auth', function($auth) {
          return $auth.validateUser();
        }]
      }
    })
    .when('/groups', {
      templateUrl: 'views/groups.html',
      controller: 'GroupsCtrl'
    })
    .when('/sign_in', {
      templateUrl: 'views/user_sessions/new.html',
      controller: 'UserSessionsCtrl'
    })
    .when('/sign_up', {
      templateUrl: 'views/user_registrations/new.html',
      controller: 'UserRegistrationsCtrl'
    })
    .otherwise({
      redirectTo: '/'
    });
}]);

app.config(['$authProvider', function($authProvider) {
  $authProvider.configure({
    apiUrl: '/api'
  });
}]);

app.factory('Announcement', ['railsResourceFactory', function (railsResourceFactory) {
  return railsResourceFactory({ url: '/api/announcements', name: 'announcement' });
}]);

app.factory('Group', ['railsResourceFactory', function (railsResourceFactory) {
  return railsResourceFactory({ url: '/api/groups', name: 'group' });
}]);

app.run(['$rootScope', '$location', function($rootScope, $location) {
  $rootScope.$on('auth:login-success', function() {
    $location.path('/today');
  });
  $rootScope.$on('auth:logout-success', function() {
    $location.path('/sign_in');
  });
}]);

这是我的测试的样子:

'use strict';

describe('AnnouncementsCtrl', function() {
  beforeEach(module('lunchHubApp'));

  it('sets scope.announcements to an empty array', inject(function($controller, $rootScope) {
    var scope = $rootScope.$new(),
        ctrl = $controller('AnnouncementsCtrl', { $scope: scope });

    expect(scope.announcements).toEqual([]);
  }));
});

这是我的 Karma 配置:

// Karma configuration
// http://karma-runner.github.io/0.12/config/configuration-file.html
// Generated on 2014-07-18 using
// generator-karma 0.8.3

module.exports = function(config) {
  'use strict';

  config.set({
    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // base path, that will be used to resolve files and exclude
    basePath: '../',

    // testing framework to use (jasmine/mocha/qunit/...)
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: [
      'bower_components/angular/angular.js',
      'bower_components/angular-mocks/angular-mocks.js',
      'bower_components/angular-animate/angular-animate.js',
      'bower_components/angular-cookies/angular-cookies.js',
      'bower_components/angular-resource/angular-resource.js',
      'bower_components/angular-route/angular-route.js',
      'bower_components/angular-sanitize/angular-sanitize.js',
      'bower_components/angular-touch/angular-touch.js',
      'bower_components/angular-route/angular-route.js',
      'bower_components/angularjs-rails-resource/angularjs-rails-resource.js',
      'bower_components/ng-token-auth/dist/ng-token-auth.js',
      'app/scripts/app.js',
      'app/scripts/controllers/announcements.js',
      'test/spec/controllers/announcements.spec.js'
    ],

    // list of files / patterns to exclude
    exclude: [],

    // web server port
    port: 8080,

    // Start these browsers, currently available:
    // - Chrome
    // - ChromeCanary
    // - Firefox
    // - Opera
    // - Safari (only Mac)
    // - PhantomJS
    // - IE (only Windows)
    browsers: [
      'PhantomJS'
    ],

    // Which plugins to enable
    plugins: [
      'karma-phantomjs-launcher',
      'karma-jasmine'
    ],

    // Continuous Integration mode
    // if true, it capture browsers, run tests and exit
    singleRun: false,

    colors: true,

    // level of logging
    // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
    logLevel: config.LOG_INFO,

    // Uncomment the following lines if you are using grunt's server to run the tests
    // proxies: {
    //   '/': 'http://localhost:9000/'
    // },
    // URL root prevent conflicts with the site root
    // urlRoot: '_karma_'
  });
};

为什么会出现这样的错误?

【问题讨论】:

    标签: angularjs karma-runner


    【解决方案1】:

    尝试将其作为模块添加到您的测试中。 ngMocks 模块允许您本质上将匿名函数创建为模块。如果您正在执行的代码正在使用该模块的功能,那么您还必须在测试期间将该模块加载到注入器中:

    describe('AnnouncementsCtrl', function() {
      beforeEach(module('lunchHubApp'));
      beforeEach(module('ng-token-auth');
    
      it('sets scope.announcements to an empty array', inject(function($controller, $rootScope) {
        var scope = $rootScope.$new(),
            ctrl = $controller('AnnouncementsCtrl', { $scope: scope });
    
        expect(scope.announcements).toEqual([]);
      }));
    });
    

    OP 编辑​​/注释:

    所以换句话说,我想答案是模拟模块而不是试图让它工作。很公平。我能够让我的测试使用与这个答案非常相似的代码。首先,我创建了一个单独的文件来模拟ng-token-auth

    angular.module('ng-token-auth', []).provider('$auth', function() {
      return {
        configure: function() {},
        $get: []
      };
    });
    

    然后我确保将该文件包含在我的 Karma 配置中。现在这是我的新测试:

    'use strict';
    
    describe('AnnouncementsCtrl', function() {
      beforeEach(module('lunchHubApp', 'ng-token-auth'));
    
      it('sets scope.announcements to an empty array', inject(function($controller, $rootScope) {
        var scope = $rootScope.$new(),
            ctrl = $controller('AnnouncementsCtrl', { $scope: scope });
    
        expect(scope.announcements).toEqual([]);
      }));
    });
    

    运行良好。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-07
    • 2022-11-17
    • 2017-05-04
    • 2012-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-31
    相关资源
    最近更新 更多