Search code examples
javascriptangularjsmocha.jskarma-mocha

Angular - Mocha - Tests Fail when I add multiple Controllers to the same Module


When I have one controller attached to a module, I can use mocha, karma to test it successfully. But when I add two controllers to the same module, the tests fail. Why is that?

I have 2 controllers defined on the same module. I can manually test the controllers and they work.

src/app/itemListController.js
angular.module('lazyLoad', [])
  .controller('ItemListController', ['$scope', function ($scope) {
...
}]);

src/app/invoiceController.js
angular.module('lazyLoad', [])
  .controller('InvoiceController', ['$scope', function ($scope) {
...
}]);

And 2 unit-tests:

test/app/itemListController.mocha.js
'use strict';
describe('testing movies', function () {
  var scope;
  var fixture;

  beforeEach(module('lazyLoad'));

  beforeEach(inject(function ($rootScope, $controller) {
    scope = $rootScope.$new();
    fixture =  $controller('ItemListController', {$scope: scope});
  }));

  it('....', function() {});
});

test/app/invoiceController.mocha.js
'use strict';
describe('testing movies', function () {
  var scope;
  var fixture;

  beforeEach(module('lazyLoad'));

  beforeEach(inject(function ($rootScope, $controller) {
    scope = $rootScope.$new();
    fixture =  $controller('InvoiceController', {$scope: scope});
  }));

  it('....', function() {});
});

I get:

PhantomJS 1.9.8 (Mac OS X 0.0.0) testing movies "before each" hook: workFn FAILED
    the object {
      "line": 1761
      "message": "[ng:areq] Argument 'ItemListController' is not a function, got undefined
    http://errors.angularjs.org/1.4.1/ng/areq?p0=ItemListController&p1=not%20a%20function%2C%20got%20undefined"
      "name": "Error"

Now if I change the module-name for the invoiceController.js and invoiceController.mocha.js to say invoiceM then both tests work.

I must be doing something wrong...


Solution

  • You define your modules twice. When you use brackets [] to pass empty dependencies, you actually create a module and replace an old one if exists with the same name. What you need to do is:

    // Create the module, maybe in a separate place.
    angular.module('lazyLoad', []);
    
    // Attach controllers to that module:
    angular.module('lazyLoad') // HEY! SEE THIS? NO BRACKETS.
      .controller('ItemListController', ...);]
    
    angular.module('lazyLoad') // HEY! SEE THIS? NO BRACKETS.
      .controller('InvoiceController' ...);