I am stuck now for a while trying to get unit testing set up and runnning.
I have an AngularJS front-end loaded with RequireJS and r.js optimized for production, so it's all nicely in one single file. This works!
What doesn't work is getting the unit tests executed. This is nothing fancy so far, just copied a starter from a tutorial.
tests/user/user.test.js
:
define(['angular', 'angular-mocks', 'app'], function(angular, app) {
describe('Unit: UserController', function() {
beforeEach(module('user.app'));
it('should do something', function() {
console.log('did it');
});
});
});
Then I have a karma.conf.js
:
module.exports = function(config) {
config.set({
logLevel: config.LOG_DEBUG,
basePath: './',
files: [
// r.js'd app files
{pattern: 'dist/app.js', included: false},
// the tests
{pattern: 'tests/**/*.test.js', included: true},
],
excluded: ['tests/main.test.js']
frameworks: ['jasmine', 'requirejs'],
browsers: ['PhantomJS'],
plugins: [
'karma-jasmine',
'karma-junit-reporter',
'karma-phantomjs-launcher',
'karma-requirejs'
],
});
};
A main.test.js
:
var allTestFiles = [];
var TEST_REGEXP = /(spec|test)\.js$/i;
var pathToModule = function(path) {
var returnValue = path.replace(/^\/base\//, '').replace(/\.js$/, '');
return returnValue;
};
Object.keys(window.__karma__.files).forEach(function(file) {
if (TEST_REGEXP.test(file)) {
// Normalize paths to RequireJS module names.
allTestFiles.push(pathToModule(file));
}
});
require.config({
baseUrl: '/base',
paths: {
'angular-mocks': 'node_modules/angular-mocks/angular-mocks',
'app': 'dist/app',
},
deps: allTestFiles,
callback: function() {
console.log('load complete');
window.__karma__.start();
},
});
And finally a gulp
task:
var gulp = require('gulp');
var karma = require('karma').server;
gulp.task('unit-test', function(done) {
karma.start({
configFile: __dirname + '/karma.conf.js',
singleRun: true
}, function() { done(); });
}
Here and there I added some log outputs and it shows that the files are loaded.
But I am stuck getting this Error: Mismatched anonymous define()
in the tests/user/user.test.js
and I don't see what is wrong. Here is the output:
http://pastebin.com/evJPj9B3
If I name the unit test module like
define('namedtestorso', ['angular', 'angular-mocks', 'app'], function(angular, app) {
...
... I don't get an error any more but the tests are not executed. Since all examples I can recall use it as anonymous define I assume naming is not correct here. But in that case the log output is executed showing that the config callback from main.test.js
is executed twice. (Is that a hint for something?)
Would be great if anyone has an idea how to fix it/get it running or even how to go on finding out what's wrong. Thanks in advance!
I now got it running so will leave my solution here:
I think I understood a bit better now how karma
works (pls tell me if I'm wrong) and so found what I had to do.
It seems to be all about putting files into the karma.conf.js
so that they are available for the main.test.js
to be loaded. Otherwise they are out of the "context" and cannot be accessed. But when putting in there, make sure to set the included
flag to false
.
Changes to the karma.conf.js
:
files: [
...
// Also included these dependencies. All the others are minified in the
// app.js but if you don't do that, also include all project deps like
// AngularJS etc.
{ pattern: 'node_modules/jasmine-core/lib/jasmine-core/boot.js', included: false },
{ pattern: 'node_modules/angular-mocks/angular-mocks.js', included: false},
// Then I had an error in my pattern ('tests/**/*.test.js')
// Only the `main.test.js` is supposed to be included!
{ pattern: 'tests/user/user.test.js', included: false }
{ pattern: 'tests/main.test.js', included: true }
...
If I'm correct Karma creates a HTML file and files with included: true
will be loaded via script tags. That's why if using RequireJS it is important to set include
to false
since you'll get the Error: Mismatched anonymous define()
if you do. So this now makes sense to me.
After solving this issue there where some other ones with modules not found. Because I used the RequireJS optimizer, I had to "map" all my modules to the main app.js
files so that when the test JS files required a certain module, RequireJS could make sure that it is (or gets) loaded.
So I ended up changing the paths
section in main.test.js
:
paths: {
// Added these for example
'angular': '../dist/app',
'angular-ui-router': '../dist/app',
// (and also my project modules)
...
Right, that seems a bit hacky. In the meantime after solving this issue I also change my workflow to running the unit test on the dev files and rely on the other tools to work properly (and if not issues to be caught by e2e tests).
Hope it helps others in my situation!
Exactly if you go to requirejs site this error states if you have included any script tag in html this means html provided by karma
So in karma.conf.js when you include files like : files['/base/src/scripts/xyz.js'] in my opinion it is added as a script tag and u keep on getting Error: Mismatched anonymous define() module
try pattern example:{pattern: '/base/src/scripts/xyz.js', included: false} which prevents adding js in script tags
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With