Joseph hooper
Joseph hooper

Reputation: 1047

AngularJS unit testing - Class Undefined

I'm trying to write some basic tests for some controllers I have. I pass in some services that use other services. One service that is passed in, "catalog service" user a service called "metrics service". This metrics calls a Helper that is declared at the top of the file, and it's being pulled from a package defined in my dependencies section of my Config file. The code works/builds fine but the tests says that this Helper is undefined. What am I missing here?

This is the test

 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
      });


    })
  );

This is the service (which is used by logger service) that calls the undefined Helper

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
    }
  };

My karma config is below

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,


  });

Upvotes: 0

Views: 274

Answers (1)

Majesty
Majesty

Reputation: 1909

It is just some notes for your consideration and not an answer. Speaking about unit-tests, the point is to test controller/service/filter or whatever independently, that's why it called unit tests. There is other type of tests, called E2E, which is End to End, which covers all code together, but this is the whole other story.

So I would suggest you to rewrite your code like so

 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');
    });
  );

So as you see, I put loggerService mock, where method1, method2 are methods, used in CatalogController. And this is what I talking about - unit test is just to check that loggerService.method1 has been called in some particular moment, you don't need to check what exactly method1 or method2 has done, it is what you should test in loggerService test, but it is not a matter of CatalogController test. But still, I'm not sure what is the problem with HelperUtils being undefined.

Upvotes: 1

Related Questions