【问题标题】:AngularJS unit testing - Class UndefinedAngularJS 单元测试 - 类未定义
【发布时间】:2019-06-19 17:55:48
【问题描述】:

我正在尝试为我拥有的一些控制器编写一些基本测试。我传入了一些使用其他服务的服务。传入的一项服务,“目录服务”用户使用称为“指标服务”的服务。该指标调用在文件顶部声明的 Helper,它是从我的 Config 文件的依赖项部分中定义的包中提取的。代码可以正常工作/构建,但测试表明此 Helper 未定义。我在这里错过了什么?

这是测试

 beforeEach(module("photonControllersPreSession"));

  var $controller;
  var $rootScope;
  var $scope;
  var createController;

  var $window;
  var $location;
  var loggerService;
  var controller;

  beforeEach(
    angular.mock.module( function(
      _$controller_,
      _$rootScope_,
      _$window_,
      _$location_,
      _loggerService_
    ) {

      $controller = _$controller_;
      $rootScope = _$rootScope_;
      $window = _$window_;
      $location = _$location_;
      loggerService = _loggerService_;
      $scope = $rootScope.$new();

      controller = $controller("CatalogController", {
        $scope: $scope,
        $location: $location,
        $window: $window,
        loggerService: loggerService
      });


    })
  );

这是调用未定义 Helper 的服务(由 logger 服务使用)

declare var HelperUtils;

export class MetricsService {

public static $inject: Array<string> = ["$rootScope", "$window", Constants.Photon.SERVICE_LOGGER];
private ubmHelper;
private dimensions: Array<any> = [];
private metricList = null;
private TAG = "MetricsService";
private trackingScopes: any = {};
private isEditing = false;

constructor(protected $rootScope, protected  $window:Interfaces.IPhotonWindowObject, protected loggerService: LoggerService, protected hiddenBrowserDetectionService: Services.HiddenBrowserDetectionService) {
  let ubmOptions = {
    idleInterval: 3000,
    submitInterval: 5000,
    header: {},
    logLevel: HelperUtils.LogLevelEnum.INFO,
    properties: {
      test : accountID
    }
  };

我的业力配置在下面

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/...)
    // as well as any additional frameworks (requirejs/chai/sinon/...)
    frameworks: [
      "jasmine",
      "karma-typescript"
    ],

    // list of files / patterns to load in the browser
    files: [
      "vendor/jquery/dist/jquery.js",
      "vendor/angular/angular.js",
      "vendor/angular-animate/angular-animate.js",
      "vendor/angular-cookies/angular-cookies.js",
      "vendor/angular-messages/angular-messages.js",
      "vendor/angular-resource/angular-resource.js",
      "vendor/angular-route/angular-route.js",
      "vendor/angular-sanitize/angular-sanitize.js",
      "vendor/angular-touch/angular-touch.js",
      "vendor/angular-mocks/angular-mocks.js",
      //"app/photon-app.js",
      "app/scripts/commons/providers/ui-notification.js",
      "app/scripts/commons/constants.ts",
      "app/constants-global.ts",
      "app/scripts/commons/interfaces/*.ts",
      "app/scripts/commons/factories/*.ts",
      "app/scripts/commons/services/*.ts",
      "app/**/*.ts",
      "test/specs/**/*.ts",
      {
        pattern: '**/*.js.map',
        included: false
      }
    ],

    // list of files / patterns to exclude
    exclude: [
      "photon/**/*.d.ts",
      "app/scripts/commons/services/message-service.ts" //TODO: please add this servcie back after basic sannity test are passing
    ],

    //This is neede to load all *spec.ts 
    mime: {
      'text/x-typescript': ['ts']
    },


    karmaTypescriptConfig: {
      "compilerOptions": {
        "moduleResolution": "node",
        "noLib": false,
        "removeComments": true,
        "target": "es5",
        // or es3, es6
        "declaration": false
        // Not compile .d.ts files

      },
      "exclude": [
        "photon/**/*.d.ts",
        "app/scripts/commons/services/message-service.ts" //TODO: please add this servcie back after basic sannity test are passing
      ],
      "include": [
        "app/scripts/commons/constants.ts",
        "app/constants-global.ts",
        "app/scripts/commons/interfaces/*.ts",
        "app/scripts/commons/factories/*.ts",
        "app/scripts/commons/services/*.ts",
        "app/**/*.ts"
        //"test/specs/**/*.ts"
      ]
    },

    // web server port
    port: 8080,

    browsers: [
      "Chrome"
    ],

    // Which plugins to enable
    plugins: [
      "karma-phantomjs-launcher",
      "karma-chrome-launcher",
      "karma-jasmine",
      "karma-coverage",
      "karma-junit-reporter",
      "karma-typescript"
    ],

    reporters: ["progress", "junit", "coverage"],

    preprocessors: {
      "app/**/*.ts": ['karma-typescript']
    },
    bundlerOptions: {
      transforms: [
        require("karma-typescript-es6-transform")()
      ]
    },

    coverageReporter: {
      reporters: [{
        type: 'cobertura',
        dir: 'coverage',
        file: 'coverage.xml'
      }, {
        type: 'html',
        dir: 'coverage'
      }, {
        type: 'text-summary'
      }]
    },

    junitReporter: {
      //outputDir: "../build/brazil-unit-tests", // results will be saved as $outputDir/$browserName.xml
      //outputDir: "../build/brazil-unit-tests/test-results.xml", // results will be saved as $outputDir/$browserName.xml
      outputFile: "../build/brazil-unit-tests/test-results.xml", // if included, results will be saved as $outputDir/$browserName/$outputFile
      suite: "PhotonPortal", // suite will become the package name attribute in xml testsuite element
      useBrowserName: false, // add browser name to report and classes names
      nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element
      classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element
      properties: {} // key value pair of properties to add to the <properties> section of the report
    },

    // 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_DEBUG,


  });

【问题讨论】:

  • 你能发布你的 Karma 配置文件吗?我认为问题在于 HelperUtils 是一个 JavaScript 全局文件,但声明的文件不是由业力加载的。还有你说的配置文件是什么意思?
  • 是的,这就是我的想法,但声明它的服务文件应该被“app/scripts/commons/services/*.ts”覆盖,我的意思是我的包配置文件,所有依赖项都在其中列出。
  • @Josephhooper 您能否提供您收到的确切错误消息?
  • @LuninRoman ReferenceError: HelperUtils 未定义

标签: angularjs typescript unit-testing karma-jasmine


【解决方案1】:

这只是供您考虑的一些注释,而不是答案。说到单元测试,重点是测试控制器/服务/过滤器或任何独立的东西,这就是它称为单元测试的原因。还有其他类型的测试,称为E2E,即End to End,它涵盖了所有代码,但这是另一回事。

所以我建议你像这样重写你的代码

 beforeEach(
    angular.mock.module( function(
      _$controller_,
      _$rootScope_,
      _$window_,
      _$location_,
    ) {
      $controller = _$controller_;
      $rootScope = _$rootScope_;
      $window = _$window_;
      $location = _$location_;
      loggerService = jasmine.createSpyObj('loggerService', ['method1', 'method2']);
      $scope = $rootScope.$new();

      controller = $controller("CatalogController", {
        $scope: $scope,
        $location: $location,
        $window: $window,
        loggerService: loggerService
      });
    })

    it('should test some CatalogController method', function () {
        CatalogController.someMethod();

        expect(loggerService.method1).toHaveBeenCalledTimes(1);
        expect(loggerService.method1).toHaveBeenCalledWith('whatever');
    });
  );

如你所见,我将loggerService 模拟,其中method1method2 是方法,用于CatalogController。这就是我所说的 - 单元测试只是检查 loggerService.method1 是否在某个特定时刻被调用,你不需要检查 method1method2 到底做了什么,这是你应该做的在loggerService 测试中测试,但这不是CatalogController 测试的问题。但是,我仍然不确定HelperUtils 未定义有什么问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-12
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-13
    • 2015-01-18
    • 2015-04-01
    相关资源
    最近更新 更多