Testing service in Angular returns module is not defined

Unit TestingAngularjsKarma Runner

Unit Testing Problem Overview


I am trying to run the default service unit test in my project (Taken from the Angular Seed project on GitHub), but I keep getting the error "module is not defined".

I have read that it could be something to do with the order of the referenced JavaScript files, but I can't seem to get it to work, so hopefully one of you might be able to help.

My configuration for the test looks like this:

> basePath = '../'; > > files = [
'public/javascripts/lib/jquery-1.8.2.js',
> 'public/javascripts/lib/angular.js',
> 'public/javascripts/lib/angular-.js',
> 'public/app.js',
> 'public/controllers/
.js',
'public/directives.js',
> 'public/filters.js',
'public/services.js',
JASMINE,
> JASMINE_ADAPTER,
'public/javascripts/lib/angular-mocks.js',
> 'test/unit/*.js' ]; > > autoWatch = true; > > browsers = ['Chrome']; > > junitReporter = { outputFile: 'test_out/unit.xml', suite: 'unit' > };

The service looks like the following:

angular.module('myApp.services', []).
  value('version', '0.1');

The test looks like this:

'use strict';
   
describe('service', function() {
  beforeEach(module('myApp.services'));


  describe('version', function() {
    it('should return current version', inject(function(version) {
      expect(version).toEqual('0.1');
    }));
  });
});

And the error when running the test through testacular is this:

> ReferenceError: module is not defined

Unit Testing Solutions


Solution 1 - Unit Testing

You are missing the angular-mocks.js file.

Solution 2 - Unit Testing

I had the same problem, and I understood why it wasn't working: The jasmine.js javascript must be referenced BEFORE the angular-mocks.js file. Indeed, the angular-mocks.js checks if Jasmine is loaded, and only if it is it will add the module function to the window.

Here is an extract of Angular Mocks code:

(Edit after the few comments about 'hacking' I had below: this is just an extract of the code, this is not something you need to write yourself, it's already there!)

window.jasmine && (function(window) {

[...]
  
  window.module = angular.mock.module = function() {
    var moduleFns = Array.prototype.slice.call(arguments, 0);
    return isSpecRunning() ? workFn() : workFn;
    /////////////////////
    [...]
  };

In a nutshell: Just reference your jasmine.js before angular-mocks.js and off you go.

Solution 3 - Unit Testing

The window.module function comes in angular-mocks.js and is a shorthand for angular.mock.module. As mentioned in the docs, the module function only works with Jasmine.

Using Testacular, the following example configuration file will load angular-mocks.js.

/** example testacular.conf.js */

basePath = '../';
files = [
  JASMINE,
  JASMINE_ADAPTER,
  'path/to/angular.js',
  'path/to/angular-mocks.js',   // for angular.mock.module and inject.
  'src/js/**/*.js',             // application sources
  'test/unit/**/*.spec.js'      // specs
];
autoWatch = true;
browsers = ['Chrome'];

And, as suggested elsewhere, you can run Testacular with debug logging to see what scripts are loaded (you can also see the same in the inspector):

testacular --log-level debug start config/testacular.conf.js

The angular.mock.inject docs include a pretty complete example.

Solution 4 - Unit Testing

We use 'module' without 'angular' in our unit tests and it works fine.

CoffeeScript:

describe 'DiscussionServicesSpec', ->
    beforeEach module 'DiscussionServices'
    beforeEach inject ... etc.

which compiles to

JavaScript:

describe('DiscussionServices', function() {
    beforeEach(module('DiscussionServices'));
    beforeEach(inject(function ... etc.

The only time I see something like the error you described is if in the testacular.conf.js file the angular-mocks.js file is not listed in the files section before the specs trying to use 'module'. If I put it after my tests in the 'files' list I get

ReferenceError: Can't find variable: module

(Our tests are being run through PhantomJS)

Solution 5 - Unit Testing

I had included angular-mocks.js in my karma config, but was still getting the error. It turns out the order is important in the files array. (duh) Just like in the head of an html doc, if a script calls angular before it's defined, and error occurs. So I just had to include my app.js after angular.js and angular-mocks.js.

Solution 6 - Unit Testing

If you're using Yeoman and its angular-generator, you probably get this error. Especially when you do the Tutorial ( ._.)
I fixed it, by copying the angular-mocks.js file, from the bower_components/angular-mocks dir to the test/mock dir. Of course you have to be sure, that your karma.conf.js file is configured correctly.
Greetings!

Solution 7 - Unit Testing

I had this same issue when I was doing something like var module = angular.module('my',[]). I needed to make sure it was surrounded by IIFE

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDofsView Question on Stackoverflow
Solution 1 - Unit TestingJohn DoeView Answer on Stackoverflow
Solution 2 - Unit TestingAntoine JaussoinView Answer on Stackoverflow
Solution 3 - Unit TestingTim SchaubView Answer on Stackoverflow
Solution 4 - Unit TestingRyan O'NeillView Answer on Stackoverflow
Solution 5 - Unit TestingErikView Answer on Stackoverflow
Solution 6 - Unit TestingalxUView Answer on Stackoverflow
Solution 7 - Unit TestingJackieView Answer on Stackoverflow