Testing service in Angular returns module is not defined

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

76322 次浏览

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)

You are missing the angular-mocks.js file.

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.

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.

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.

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!

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