Ozrix Ozrix - 6 months ago 44
AngularJS Question

Karma + RequireJS + AngularJS, shimmed scripts not loading in spec

While using Karma + Jasmine + RequireJS + AngularJS, I'm unable to load any of my shimmed scripts, for example

angular-mocks
, into the test specs. The file seem to be served all right, just doesn't work in the spec.

UPDATE Angular is global, and the corresponding shim doesn't affect it.

enter image description here

In
Karma.conf.js
, I'm including
angular-mocks
to be loaded by RequireJS:

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', 'requirejs'],


// list of files / patterns to load in the browser
files: [
{pattern: 'node_modules/angular-mocks/angular-mocks.js', included: false},
...
'test/euro-2016/main-test.js'
],


// list of files to exclude
exclude: [
'main/main-euro-2016.js'
],


// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'../../*.html': ['ng-html2js']
},


// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],

// web server port
port: 9876,


// enable / disable colors in the output (reporters and logs)
colors: true,


// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_DEBUG,


// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,


// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['PhantomJS'],


// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,

// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})


};

The RequireJS shim in the Karma main file
main-test.js
:

var tests = [];
for (var file in window.__karma__.files) {
if (window.__karma__.files.hasOwnProperty(file)) {
if (/Spec\.js$/.test(file)) {
tests.push(file);
}
}
}

requirejs.config({
// Karma serves files from '/base'
baseUrl: "/base",

paths: {
"angular": "vendor/angular/angular",
"angularMocks": "node_modules/angular-mocks/angular-mocks",
"jquery": "vendor/jquery/jquery.min",
...
},

shim: {
"angular": {
exports: "angular",
deps: ['jquery']
},
"angularMocks": {
exports: "angularMocks",
deps: ['angular']
},
...
},

// ask Require.js to load these files (all our tests)
deps: tests,

// start test run, once Require.js is done
callback: window.__karma__.start
});


The spec file:

define(['angular', 'modules/euro-2016/app', 'angularMocks'], function(angular, app, mocks){
console.log("ANGULAR", angular); // ok
console.log("APP", app); // ok
console.log("MOCKS", mocks); // undefined
})


enter image description here

Answer

Looking at the source code that is installed by installing the NPM package angular-mocks, specifically the file node_modules/angular-mocks/angular-mocks.js, here is what I see:

  1. There is no mention of angularMocks anywhere in that code, therefore exporting angularMocks cannot work.

  2. Conversely, the plugin installs itself as angular.mock. Early in the file there is the line:

    angular.mock = {};
    

    And then everything is added to angular.mock.

So you can remove your exports and access the plugin through angular.mock. This should work:

define(['angular', 'modules/euro-2016/app', 'angularMocks'], function(angular, app){
    console.log("ANGULAR", angular);
    console.log("APP", app);
    console.log("MOCKS", angular.mock); 
});

If you must have an exports for some reason (for instance if you use enforceDefine, which requires that all shim have exports values) you could set it to angular.mock.

Comments