Pham Minh Tan
Pham Minh Tan

Reputation: 2096

Unit-Testing AngularJS: Uncaught Error: [$injector:nomod] Module is not available! and ReferenceError: module is not defined when run Karma

I've a small unitTest in Jasmine run with Karma. But when i run Karma it show errors:

Uncaught Error: [$injector:nomod] Module 'material.controllers' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.

FAILED Unit: LoginController encountered a declaration exception

ReferenceError: module is not defined

Here are my source code, config Karma file and unitTest.

karma.conf.js

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',


    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],


    // list of files / patterns to load in the browser
    files: [
      '/home/tanpham/Angular/Dev/libs/angular/angular.js',
      '/home/tanpham/Angular/Dev/js/**/*.js',
      '/home/tanpham/Angular/Dev/js/*.js',
      '/home/tanpham/Angular/Test/*.js'
    ],


    // list of files to exclude
    exclude: [
    ],


    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
    },

index.html

<body ng-app="material" ng-controller="AppController">
    <ui-view></ui-view>
</body>

app.js

angular.module('material.controllers', []);
angular.module('material.services', []);
angular.module('material.directives',[]);
angular.module('material.filters',[]);
var app = angular.module('material', ['ui.router','material.directives','http-auth-interceptor','material.controllers','material.services','material.filters'])
.config(function($stateProvider, $urlRouterProvider,$locationProvider) {
    $stateProvider
    .state('app', {
        url: "/app",
        abstract: true,
        templateUrl: "views/app.html"
    }).state('login', {
        url: "/login",
        templateUrl: "views/login.html",
        controller: "LoginController"
    });
    
    $urlRouterProvider.otherwise('/login');
})

loginController

angular.module('material.controllers').controller('LoginController', function($scope) {
    
      $scope.name = "Ari";
      $scope.sayHello = function() {
         $scope.greeting = "Hello " + $scope.name;
      }
});

helloSpec.js

describe('Unit: LoginController', function() {
    
      // Load the module with LoginController
      beforeEach(module('material.controllers'));

      var ctrl, scope;
      // inject the $controller and $rootScope services
      // in the beforeEach block
      beforeEach(inject(function($controller, $rootScope) {
        // Create a new scope that's a child of the $rootScope
        scope = $rootScope.$new();
        // Create the controller
        ctrl = $controller('LoginController', {
          $scope: scope
        });
      }));
    
      it('should create $scope.greeting when calling sayHello', 
        function() {
          expect(scope.greeting).toBeUndefined();
          scope.sayHello();
          expect(scope.greeting).toEqual("Hello Ari");
      });
    
})

So, i can do with that and my module's name is right?

Upvotes: 4

Views: 17546

Answers (2)

Jet Geng
Jet Geng

Reputation: 357

i have met this issue. and solved it. just add ",[]" behind the module name in the module declare statement。 in this case chaged code will be :

angular.module('material.controllers',[])
 .controller('LoginController', function($scope) {

  $scope.name = "Ari";
  $scope.sayHello = function() {
     $scope.greeting = "Hello " + $scope.name;
  }
});

Upvotes: 1

Madhan Ganesh
Madhan Ganesh

Reputation: 2293

Check the order in which the angular modules are loaded. As your listing of javascript files in karma conf, see if the module defined files are loaded first before other files that use it.

Adjust the order in this listing, are explicitly load the file where 'material.controllers' module is defined.

files: [
  '/home/tanpham/Angular/Dev/libs/angular/angular.js',
  '/home/tanpham/Angular/Dev/js/**/*.js',
  '/home/tanpham/Angular/Dev/js/*.js',
  '/home/tanpham/Angular/Test/*.js'
],

Upvotes: 8

Related Questions