Javascript – Karma error Argument ‘Controller’ is not a function, got undefined

angularjsjasminejavascriptkarma-jasminekarma-runner

I got a problem when I tried to test my controller. When I run my test I got an error

Error: [ng:areq] Argument 'MainCtrl' is not a function, got undefined   http://errors.angularjs.org/1.3.8/ng/areq?p0=MainCtrl&p1=not%20a%20function%2C%20got%20undefined
        at assertArg (/Users/tetianachupryna/project/bower_components/angular/angular.js:1577)
        at assertArgFn (/Users/tetianachupryna/project/bower_components/angular/angular.js:1588)
        at /Users/tetianachupryna/project/bower_components/angular/angular.js:8418
        at /Users/tetianachupryna/project/src/spec/controllers/main-controller.spec.js:11
        at /Users/tetianachupryna/project/src/spec/controllers/main-controller.spec.js:17
        at /Users/tetianachupryna/project/node_modules/karma-jasmine/lib/adapter.js:184
        at http://localhost:9877/karma.js:185
        at http://localhost:9877/context.html:51

I know that SO is full of similar questions. But I'm a total null in Angular and JS in general, so those answers didn't help me. From similar questions on SO I discovered that my problem is in wrong definition of the controller but I still can't figure out what I did wrong. I've stack and I'm begging for your help.

First of all here is my src/app/index.js file where my module is defined

var app = angular.module('myModule', [
  'ngAnimate',
  'ngSanitize',
  'ngResource',
  'ui.router',
  'pascalprecht.translate',
  'thing1',
  'thing2']);

Here is src/app/controllers/main-controller.js

angular.module('myModule').controller('MainCtrl', [
    '$scope',
    '$state',
    function ($scope, $state) {
      $scope.state = $state;
      //***
      $scope.isBigStep = function isBigStep() {
        return $state.$current.step == 3;
      };    
  }]);

And finally this a file with the test src/spec/controllers/main-controller.spec.js

describe('MainCtrl', function() {
  var scope, $state, createController;

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

    createController = function() {
      return $controller('MainCtrl', {
        '$scope': scope
      });
    };
  }));

  it('should make 3 as current step', function() {
    var controller = createController();
    expect(scope.isBigStep()).toBe(true);
  });
});

In karma config I have all those files

files: [
      'bower_components/angular/angular.js',
      'bower_components/angular-mocks/angular-mocks.js',
      'src/app/index.js',
      'src/app/controllers/*.js',
      'src/spec/controllers/*.js'
    ],

For run my test I use karma-runner plugin in RubyMine.

I'd be thankful for any help!

Best Answer

What you are missing is to add the module in the beforeEach hook for test setup. Otherwise the controller will not be found. So add beforeEach(module('myModule')).

describe('MainCtrl', function() {
  var scope, $state, createController;

  beforeEach(module('myModule')); //<--- Hook module

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

    createController = function() {
      return $controller('MainCtrl', {
        '$scope': scope
      });
    };
  }));

  it('should make 3 as current step', function() {
    var controller = createController();
    expect(scope.isBigStep()).toBe(true);
  });
});
Related Topic