0
votes

I'm trying to test my app, which has each controller defined on it's own module i.e., not as a controller of the app module, and then loaded as a dependency of the main app module. When I try to run a test that just checks that the loginController is defined, using Karma/Jasmine, I get the following output:

'Expected undefined to be defined.'

edit

I updated login.controller.spec and switched the karma browser to chrome, which gave me more useful debug info. Now I'm getting an error related to a factory that is added to $httpProvider.interceptors in the main app file:

Unknown provider: authFactoryProvider <- authFactory <- $http <- $translateStaticFilesLoader <- $translate

I found similar issues related to this which were resolved by including angular-translate-loader-static-files.js, which is being loaded when karma runs:

DEBUG [web-server]: serving (cached): /path/to/my/app/bower_components/angular-translate-loader-static-files/angular-translate-loader-static-files.js

How do I resolve all these dependency issues with karma?

index.js

'use strict';

angular.module('app',
    [
    //'mockBackend', //uncomment when loading mock backend
    'ngAnimate',
    'ngCookies',
    'ngTouch',
    'ngSanitize',
    'ngResource',
    'ui.bootstrap',
    'ui.router',
    'ui.router.stateHelper',
    'pascalprecht.translate',
    'utilsModule',
    'loginModule',
    'vsmsPackageModule',
    'vsmsCampaignModule',
    'vdmsCampaignModule',
    'vdmsDashboardModule',
    'daterangepicker',
    'ui.event',
    'idmAdminModule',
    'helpdeskModule',
    'ncy-angular-breadcrumb',
    'rzModule',
    'vsmsDashboardModule',
    'highcharts-ng',
    'permission',
    'dndLists'
    ])
  .config(function ($stateProvider, $urlRouterProvider, $httpProvider, $locationProvider, $translateProvider, $breadcrumbProvider, $compileProvider) {
    $urlRouterProvider.otherwise('/');
    //initialize get if not there
    if (!$httpProvider.defaults.headers.get) {
      $httpProvider.defaults.headers.get = {};
    }
    //disable IE ajax request caching
    $httpProvider.defaults.headers.get['If-Modified-Since'] = 'Mon, 26 Jul 1997 05:00:00 GMT';
    // extra
    $httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache';
    $httpProvider.defaults.headers.get['Pragma'] = 'no-cache';

    $locationProvider.html5Mode({
      enabled: false,
      requireBase: false
    });
    $translateProvider.useSanitizeValueStrategy('sanitize');
    $translateProvider.useStaticFilesLoader({
      prefix: '/locales/',
      suffix: '.json'
    });

    $translateProvider
    .preferredLanguage('en_us')
    .fallbackLanguage('en_us');

    $breadcrumbProvider.setOptions({
      templateUrl: 'components/templates/breadcrumb.tpl.html'
    });
    $compileProvider.debugInfoEnabled(false);
    // $compileProvider.aHrefSanitizationWhitelist(/^\s*(|blob|):/);
    $httpProvider.interceptors.push('authFactory');
        $httpProvider.interceptors.push('headersFactory');
   })

login.module.js

angular.module('loginModule', []);

login.controller.js

  angular.module('loginModule')
  .controller('loginController', login);

  login.$inject = [
      '$log',
      '$uibModal',
      '$rootScope',
      'storageFactory',
      'loginFactory',
      '$state',
      'RoleStore',
      'PermissionStore'
  ];

  function login($log, $uibModal, $rootScope, storageFactory, loginFactory, $state, RoleStore, PermissionStore) {

      /* jshint validthis: true */
      var vm = this;
      vm.loginUser = loginUser;
      vm.forgotPassword = forgotPassword;
      vm.errorCode = null;
      PermissionStore.clearStore();

      function loginUser() {
      ...

I'm just trying to test if the controller exists and I can't get past the error:

Expected undefined to be defined.

login.controller.spec.js

describe('loginController', function() {

  beforeEach(module('app'));

  var $controller,
  $scope,
  $log,
  $uibModal,
  $rootScope,
  storageFactory,
  loginFactory,
  $state,
  RoleStore,
  PermissionStore,
  vsmsCoreFactory;

  beforeEach(inject(function(_$controller_, _$log_, _$uibModal_, _$rootScope_, _storageFactory_, _loginFactory_, _$state_, _RoleStore_, _PermissionStore_, _vsmsCoreFactory_){
    $controller = _$controller_;
    $scope = $rootScope.new();
    $log = _$log_;
    $uibModal = _$uibModal_;
    $rootScope = _$rootScope_;
    storageFactory = _storageFactory_;
    loginFactory = _loginFactory_;
    $state = _$state_;
    RoleStore = _RoleStore_;
    PermissionStore = _PermissionStore_;
    vsmsCoreFactory = _vsmsCoreFactory_;
  }));

  describe('vm.loginUser', function() {
    it('should be defined', function() {
      var loginController = $controller('loginController', {
        $log: $log,
        $uibModal: $uibModal,
        $rootScope: $rootScope,
        storageFactory: storageFactory,
        loginFactory: loginFactory,
        $state: $state,
        RoleStore: RoleStore,
        PermissionStore: PermissionStore,
        vsmsCoreFactory: vsmsCoreFactory
      });
      expect(loginController).toBeDefined();
      // expect(testController.model.name).toEqual("controllerAs vm test");
    });
  });

});

unit-tests.js

'use strict';

var gulp = require('gulp');

var $ = require('gulp-load-plugins')();

var wiredep = require('wiredep');

var paths = gulp.paths;

function runTests (singleRun, done) {
  var bowerDeps = wiredep({
    directory: 'bower_components',
    exclude: ['bootstrap-sass-official'],
    dependencies: true,
    devDependencies: true
  });

  var testFiles = bowerDeps.js.concat([
    './src/app/index.js',
    './src/components/scripts/ui-bootstrap-custom-tpls-2.1.3.js',
    './src/{app,components}/**/*.module.js',
    './src/{app,components}/**/*.factory.js',
    './src/{app,components}/**/*.controller.js',
    './src/{app,components}/**/*.spec.js'
  ]);

  gulp.src(testFiles)
    .pipe($.karma({
      configFile: 'karma.conf.js',
      action: (singleRun)? 'run': 'watch'
    }))
    .on('error', function (err) {
      // Make sure failed tests cause gulp to exit non-zero
      throw err;
    });
}

gulp.task('test', function (done) { runTests(true /* singleRun */, done) });
gulp.task('test:auto', function (done) { runTests(false /* singleRun */, done) });
2

2 Answers

0
votes

Please refer the the below link it is already answered.

How to inject controller dependencies in Jasmine tests?

loginController dependencies are not passed in your unit test.

The second parameter of $controller is for controller dependencies.

Empty dependency is passed.

$controller('loginController', {});

Make sure all the dependent modules are loaded before testing loginColtroller.

I have modified your code. I hope it will work.

'use strict';

describe('loginController', function() {

  beforeEach(module('loginModule'));

  var loginController;

  beforeEach(inject(function($controller, _$log_, _$uibModal_, _$rootScope_, _storageFactory_, _loginFactory_, _$state_, _RoleStore_, _PermissionStore_ ){
    scope = _$rootScope_.$new();
    loginController = $controller('loginController', 
    {   // all dependencies has to be passed in order
        '$log' : _$log_,
        '$uibModal' : _$uibModal_,
        '$rootScope' : _$rootScope_,
        'storageFactory' : _storageFactory_,
        'loginFactory': _loginFactory_,
        '$state': _$state_,
        'RoleStore': _RoleStore_,
        'PermissionStore': _PermissionStore_
    }, 
    {});
  }));

  it('should be defined', function() {
    expect(loginController).toBeDefined();
  });

});
0
votes

The issue is with your login.module.js file.

You'll have to inject ui.bootstrap and ui.router as dependencies while defining the loginModule. Otherwise it will not be able to get $uibModal and $state while defining the loginController.

This should be the definition of your loginModule

angular.module('loginModule', ['ui.bootstrap', 'ui.router']);

PS: I'm assuming here that storageFactory, loginFactory, RoleStore and PermissionStore are defined on loginModule itself.

Hope this helps!