在angularjs中运行karma测试时来自config的其他http请求

时间:2014-02-14 23:49:34

标签: angularjs karma-runner

我正在尝试设置一个Karma测试套件,我的代码的基线是mean stack。我正在尝试编写一些测试(特别是登录),它看起来像:

(function() {
  describe('LoginController', function() {
    beforeEach(module('mean'));

    var scope, rootScope, LoginController, $httpBackend, $location;

    beforeEach(inject(function($controller, $rootScope, _$httpBackend_, _$location_) {
      scope = $rootScope.$new();
      rootScope = $rootScope.$new();

      LoginController = $controller('LoginController', {
        $scope: scope,
        $rootScope: rootScope
      });

      $httpBackend = _$httpBackend_;

      $location = _$location_;
    }));

    it('should show danger when wrong credentials are used', function() {
      scope.credentials = {
        email: 'test@email.com',
        password: 'password'
      }

      $httpBackend.expectPOST('/api/v1/user/auth').respond({
        status: 'error',
        error: 'Invalid User'
      });


      scope.authenticate();
      $httpBackend.flush();

      expect(scope.status_object).toEqualData({text: 'Invalid User', class: 'danger', show: true});
    });
  });
})();

在我的public/js/config.js中,我有一些额外的逻辑可以加载其他一些http请求。在我的karma控制台中,我得到:

WARN [web-server]: 404: /lang/en-US.json
WARN [web-server]: 404: /api/v1/user/session
PhantomJS 1.9.7 (Mac OS X) LoginController should show danger when wrong credentials are used FAILED
    Error: Unexpected request: GET /lang/en-US.json
    Expected POST /api/v1/user/auth

如何设置我的测试以获得那些?

karma.conf.js

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

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


        // frameworks to use
        frameworks: ['jasmine'],


        // list of files / patterns to load in the browser
        files: [
            'public/lib/angular/angular.js',
            'public/lib/angular-mocks/angular-mocks.js',
            'public/lib/angular-cookies/angular-cookies.js',
            'public/lib/angular-resource/angular-resource.js',
            'public/lib/angular-route/angular-route.js',
            'public/lib/angular-strap/dist/angular-strap.min.js',
            'public/lib/angular-animate/angular-animate.min.js',
            'public/lib/angular-bootstrap/ui-bootstrap-tpls.js',
            'public/lib/angular-bootstrap/ui-bootstrap.js',
            'public/lib/angular-translate/angular-translate.min.js',
            'public/lib/angular-animate/angular-animate.min.js',
            'public/lib/angular-translate-loader-static-files/angular-translate-loader-static-files.js',
            'public/lib/angular-translate-storage-cookie/angular-translate-storage-cookie.js',
            'public/js/**/*.js',
            'test/karma/unit/**/*.js'

        ],


        // list of files to exclude
        exclude: [
            'test/coverage/**/*.*'
        ],


        // test results reporter to use
        // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
        //reporters: ['progress'],
        reporters: ['progress', 'coverage'],

        // coverage
        preprocessors: {
            // source files, that you wanna generate coverage for
            // do not include tests or libraries
            // (these files will be instrumented by Istanbul)
            'public/js/controllers/**/*.js': ['coverage'],
            'public/js/services/**/*.js': ['coverage'],
            'public/js/config.js': ['coverage'],
        },

        coverageReporter: {
            type: 'html',
            dir: 'test/coverage/'
        },

        // web server port
        port: 9876,


        // enable / disable colors in the output (reporters and logs)
        colors: true,


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


        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: true,


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


        // If browser does not capture in given timeout [ms], kill it
        captureTimeout: 60000,


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

我的public/js/config.js有:

.run(['$rootScope', '$location', 'UserService', 'CompanyService', function($rootScope, $location, UserService, CompanyService) {
  $rootScope.globals = {};

  $rootScope.$on('login', function(event, data) {
    $rootScope.api_key = data.api_key;
    CompanyService.get(data.user.company_id);
  });

  UserService.checkAuth().then(function(response) {
    if(response.data.user) {
      // Logged in user
      $rootScope.$broadcast('login', response.data);

      $rootScope.$watch(function () {return $location.path()}, function (newLocation) {
        $rootScope.globals.accessPath = newLocation.split('/')[1];

        if(newLocation !== '/login') {
          if(UserService.getAccess() !== $rootScope.globals.accessPath) {
            alert('Invalid access');
            UserService.logout();
          }
        } else {
          $location.path(UserService.getAccess());
        }
      });
    } else {
      UserService.logout();
    }
  });
}]);

1 个答案:

答案 0 :(得分:5)

您可以将对 UserService.checkAuth()的调用解压缩到另一个模块,例如'init-module'并在该模块的运行块中调用。 然后让你的模块依赖于init-module,以便Angular加载它并执行它的运行块:

angular.module('init-module', []).run(function() {
     // call UserService.checkAuth() here
})
angular.module('my-production-module', ['init-module']);

进行单元测试时,您可以通过执行以下命令在规范运行之前模拟整个init-module:

angular.module('init-module', function () {});

来自AngularJS module documentation - “......将您的应用程序分解为多个模块...... ...以及一个依赖于上述模块的应用程序级模块,它具有初始化代码...... 这种分解的原因是在测试中,通常需要忽略初始化代码,这往往很难测试。通过将其放入单独的模块中,可以在测试中轻松忽略它。只需加载与测试“

相关的模块,测试也可以更集中