简体   繁体   English

使用Jasmine和Chutzpah在AngularJS中进行单元测试

[英]Unit testing in AngularJS with Jasmine and Chutzpah

I am trying to write Unit test cases for existing SPA project built on angularJS. 我正在尝试为基于angularJS构建的现有SPA项目编写单元测试用例。 I get the "Can't find variable: module" error whenever I try to execute the code. 每当我尝试执行代码时,都会收到“找不到变量:模块”错误。

I installed the libraries using npm. 我使用npm安装了库。

I used Chutzpah and Jasmine libraries for this. 为此使用了ChutzpahJasmine库。

appModule.js appModule.js

(function () {
    'use strict';

    angular.module('app', [
        'ngMessages',
        'ui.router',
        'ui.router.title'
    ]).run(['REQ_TOKEN', function (REQ_TOKEN) {
        //...
    }]).config(['$httpProvider', function ($httpProvider) {
        $httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
    }]);
})();

site.js site.js

(function () {
    'use strict';

    window.deferredBootstrapper.bootstrap({
        element: window.document,
        module: 'app',
        resolve: {
            REQ_TOKEN: ['$http', function ($http) {
                return $http.get('/.../', { ignoreLoadingBar: true, params: { ts: new Date().getTime() } });
            }]
        }
    });
})();

appController.js: appController.js:

(function () {
'use strict';

  angular
      .module('app')
      .controller('appController', appController);

  appController.$inject = ['apiServices', '$scope'];

  function appController(apiServices, $scope) {
    $scope.value = 5;
  }
})();

apiServices.js apiServices.js

(function () {
'use strict';

  angular
      .module('app')
      .factory('apiServices', apiServices);

  apiServices.$inject = ['$http', '$log', '$q'];

  function apiServices($http, $log, $q) {
    var clientServicesPath = '/api/ClientServices',
    service =
       {  .......  };

    return service;
  }
})();

appControllerSpec.js appControllerSpec.js

/// <reference path="../../../lib/angular/angular.js" />
/// <reference path="../../../lib/angular-deferred-bootstrap/angular-deferred-bootstrap.js" />
/// <reference path="../../../lib/angular-ui-router/release/angular-ui-router.js" />
/// <reference path="../../../lib/angular-ui-router-title/angular-ui-router-title.js" />
/// <reference path="../../../lib/angular-messages/angular-messages.js" />

/// <reference path="../../modules/appmodule.js" />
/// <reference path="../../site.js" />
/// <reference path="../../factories/sharedfunctions.js" />

/// <reference path="../../services/apiservices.js" />
/// <reference path="../../controllers/appcontroller.js" />
/// <reference path="../../../../node_modules/jasmine/bin/jasmine.js" />
/// <reference path="../../../../node_modules/jasmine/lib/jasmine.js" />
/// <reference path="../../../../node_modules/jasmine-ajax/lib/mock-ajax.js" />
/// <reference path="../../../lib/angular-mocks/angular-mocks.js" />

describe('When using appController ', function () {
  //initialize Angular
  beforeEach(module('app'));   
  var ctrl, scope, apiServices;

  beforeEach(inject(function ($injector) {
    apiServices = $injector.get('apiServices');
  }));

  beforeEach(inject(function ($controller, $rootScope, apiServices) {
    scope = $rootScope.$new();
    var ctrl = $controller('appController', { $scope: scope, apiServices: apiServices });
  }));

  it('initial value is 5', function () {
    expect(scope.value).toBe(5);
  });
});

I get the following error: 我收到以下错误:

Test 'When using appController :initial value is 5' failed Error: [$injector:unpr] Unknown provider: REQ_TOKENProvider <- REQ_TOKEN http://errors.angularjs.org/1.5.1/ $injector/unpr?p0=REQ_TOKENProvider%20%3C-%20REQ_TOKEN in file:///C:/Users/Bhanu/......./lib/angular/angular.js (line 4418) at getService (file:///C:/Users/Bhanu/......./lib/angular/angular.js:4571:46) at file:///C:/Users/Bhanu/......./lib/angular/angular.js:4423:48 at getService (file:///C:/Users/Bhanu/......./lib/angular/angular.js:4571:46) at injectionArgs (file:///C:/Users/Bhanu/......./lib/angular/angular.js:4595:68) at invoke (file:///C:/Users/Bhanu/......./lib/angular/angular.js:4617:31) Error: [$injector:unpr] Unknown provider: REQ_TOKENProvider <- REQ_TOKEN http://errors.angularjs.org/1.5.1/ $injector/unpr?p0=REQ_TOKENProvider%20%3C-%20REQ_TOKEN in file:///C:/Users/Bhanu/......./lib/angular/angular.js (line 4418) at getService (file:///C:/Users/Bhanu/......./lib/angular/angular.js:4571:46) at file:///C:/Users/Bha 测试'使用appController时:初始值为5'失败错误:[$ injector:unpr]未知提供程序:REQ_TOKENProvider <-REQ_TOKEN http://errors.angularjs.org/1.5.1/ $ injector / unpr?p0 = REQ_TOKENProvider% getService(file:/// C:/ Users)中的文件:/// C:/Users/Bhanu/......./lib/angular/angular.js(第4418行)中的20%3C-%20REQ_TOKEN /Bhanu/......./lib/angular/angular.js:4571:46),位于文件:/// C:/Users/Bhanu/......./lib/angular/angular。 js:4423:48在getService(文件:/// C:/Users/Bhanu/......./lib/angular/angular.js:4571:46)在injectionArgs(文件:/// C: /Users/Bhanu/......./lib/angular/angular.js:4595:68)在调用时(file:/// C:/Users/Bhanu/......./lib/ angular / angular.js:4617:31)错误:[$ injector:unpr]未知提供程序:REQ_TOKENProvider <-REQ_TOKEN http://errors.angularjs.org/1.5.1/ $ injector / unpr?p0 = REQ_TOKENProvider%20% getService(file:/// C:/ Users / Bhanu)中的文件:/// C:/Users/Bhanu/......./lib/angular/angular.js(第4418行)中的3C-%20REQ_TOKEN /......./lib/angular/angular.js:4571:46),位于文件:/// C:/ Users / Bha nu/......./lib/angular/angular.js:4423:48 at getService (file:///C:/Users/Bhanu/......./lib/angular/angular.js:4571:46) at injectionArgs (file:///C:/Users/Bhanu/......./lib/angular/angular.js:4595:68) at invoke (file:///C:/Users/Bhanu/......./lib/angular/angular.js:4617:31) in C:\\Users\\Bhanu.......\\js\\TestingJS\\controllers\\appControllerSpec.js (line 43) nu /......./ lib / angular / angular.js:4423:48(位于getService(file:/// C:/Users/Bhanu/......./lib/angular/angular。 js:4571:46)在InjectionArgs(文件:/// C:/Users/Bhanu/......./lib/angular/angular.js:4595:68)在调用(file:/// C :/ Users / Bhanu /......./ lib / angular / angular.js:4617:31)在C:\\ Users \\ Bhanu ....... \\ js \\ TestingJS \\ controllers \\ appControllerSpec.js中(第43行)

0 passed, 1 failed, 1 total (chutzpah). 0个通过,1个失败,总共1个(chutzpah)。

I have tried all the possible solutions but none worked for me. 我尝试了所有可能的解决方案,但没有一个对我有用。 I ran the tests directly by right clicking the Test controller file and selecting the option "Run JS Tests". 我通过右键单击“测试”控制器文件并选择“运行JS测试”选项直接运行测试。

I feel there are more pieces towards configuration. 我觉得还有更多关于配置的内容。 Please help me with this. 请帮我解决一下这个。

This is not the way you pass your controller services to you tests, and you are creating a new var ctrl variable withing forEach. 这不是将控制器服务传递给测试的方式,并且正在使用forEach创建新的var ctrl变量。 Also, there is a single instance of the injector per application. 此外,每个应用程序只有一个注射器实例。 You must get your controller and your service instance withing the same inject(...) 您必须使用相同的inject(...)获取控制器和服务实例inject(...)

Wrong 错误

var ctrl = $controller('appController', { $scope: scope, apiServices: apiServices });

Right

describe('When using appController ', function () {

  var ctrl, scope, apiServices;

  beforeEach(inject(function ($controller, $rootScope) {
    // Put it here for the sake of organization
    //initialize Angular
    module('app');

    scope = $rootScope.$new();
    // Get controller instance
    ctrl = $controller('appController');
    // Get service instance
    apiServices = $injector.get('apiServices');
  }));

  it('initial value is 5', function () {
    expect(scope.value).toBe(5);
  });

});

According to the documentation of deferredBootstrapper , 根据deferredBootstrapper的文档,

Since the constants that deferredBootstrapper adds to your applications module are not available in your unit tests, it makes sense to provide them in a global beforeEach(): 由于deferredBootstrapper添加到应用程序模块的常量在单元测试中不可用,因此在全局beforeEach()中提供它们是有意义的:

So, appControllerSpec.js should be 因此, appControllerSpec.js应该是

/// <reference path="../../../lib/angular/angular.js" />
/// <reference path="../../../lib/angular-deferred-bootstrap/angular-deferred-bootstrap.js" />
/// <reference path="../../../lib/angular-ui-router/release/angular-ui-router.js" />
/// <reference path="../../../lib/angular-ui-router-title/angular-ui-router-title.js" />
/// <reference path="../../../lib/angular-messages/angular-messages.js" />

/// <reference path="../../modules/appmodule.js" />
/// <reference path="../../site.js" />
/// <reference path="../../factories/sharedfunctions.js" />

/// <reference path="../../services/apiservices.js" />
/// <reference path="../../controllers/appcontroller.js" />
/// <reference path="../../../../node_modules/jasmine/bin/jasmine.js" />
/// <reference path="../../../../node_modules/jasmine/lib/jasmine.js" />
/// <reference path="../../../../node_modules/jasmine-ajax/lib/mock-ajax.js" />
/// <reference path="../../../lib/angular-mocks/angular-mocks.js" />

describe('When using appController ', function () {
  //initialize Angular
  beforeEach(module('app'));   
  var ctrl, scope, apiServices, REQ_TOKEN;

  beforeEach(function () {
      module(function ($provide) {
          $provide.constant('REQ_TOKEN', { token: '/dummyValue' });
      });
  });

  beforeEach(inject(function ($controller, $rootScope, apiServices) {
    scope = $rootScope.$new();
    REQ_TOKEN = $injector.get('REQ_TOKEN');
    apiServices = $injector.get('apiServices');
    var ctrl = $controller('appController', { $scope: scope});
  }));

  it('initial value is 5', function () {
    expect(scope.value).toBe(5);
  });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM