angularjs, karma and requirejs test case error - javascript

I am using requirejs for my angularjs application. For TDD i am using mocha. As per this article, I am writing my test cases but there is always this error that comes while executing a test case
Error: [$injector:modulerr] Failed to instantiate module sampleapp due to:
Error: [$injector:nomod] Module 'sampleapp' 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.
Test Case:
define([
'angular',
'angular-mocks'
], function() {
describe('main controller todo app', function() {
var scope, ctrl;
beforeEach(module('sampleapp',[]));
beforeEach(inject(function($rootScope, $controller) {
scope = $rootScope.$new();
ctrl = $controller('mainCtrl', {$scope: scope});
}));
it('is todo added', function() {
scope.todo = 'My new Todo';
scope.addTodo();
assert.equal(scope.todos.length, 1);
});
})
});
Karma Conf:
module.exports = function(config) {
'use strict';
config.set({
basePath: './',
frameworks: [
'requirejs',
'mocha',
'chai'
],
files: [{
pattern: 'test/test-main.js',
watched: true
}, {
pattern: 'app/angular/**/*.js',
included: false
}, {
pattern: 'app/*.js',
included: false
}, {
pattern: 'app/scripts/additional/**/*.js',
included: false
}, {
pattern: 'test/spec/**/*.js',
included: false,
watched: true
}],
exclude: [
'app/main.js'
],
reporters: ['spec'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
captureTimeout: 20000,
singleRun: false,
plugins: [
'karma-chai',
'karma-mocha',
'karma-requirejs',
'karma-spec-reporter',
'karma-chrome-launcher'
]
});
}
Test Main:
var tests = [];
var TEST_REGEXP = /test[A-Za-z0-9]{1,}-[A-Za-z0-9]{1,}\.js/i;
Object.keys(window.__karma__.files).forEach(function(file) {
if (TEST_REGEXP.test(file)) {
tests.push(file);
}
});
requirejs.config({
'baseUrl': '/base/app',
'paths': {
'angular': 'scripts/additional/angular/angular',
'angular-mocks': 'scripts/additional/angular-mocks/angular-mocks',
},
'shim': {
'angular-mocks' : {'exports' : 'angular-mocks', 'deps': ['angular']}
},
'deps': tests,
'callback': window.__karma__.start
});
Any help or direction to fix this is greatly appreciated

the main problem was that the file where my module was getting created was not loaded (i.e. the file executing code var app = angular.module("sampleapp",[]);)
Once that was corrected everything started to work

Related

Karma error: Can't find variable: angular

I'm trying for a week run karma in a project. I've follow this tutorial AngularJS Unit Test but when run karma start the console shows this error:
PhantomJS 2.1.1 (Linux 0.0.0) ERROR
ReferenceError: Can't find variable: angular
at /home/user/workspace/UnitTest/app/app.js:1
I thought the problem was in my project, so i've created a new one and the error persists.
My karma.conf.js is
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'app/*.js',
'tests/*.js',
'node_modules/angular/angular.js',
'node_modules/angular/angular.min.js',
'node_modules/angular-mocks/angular-mocks.js'
],
exclude: [
],
preprocessors: {
},
reporters: ['progress'],
// web server port
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['PhantomJS'],
customLaunchers: {
Chrome_without_security: {
base: 'PhantomJS',
flags: ['--disable-web-security']
}
},
singleRun: false,
concurrency: Infinity
})
}
and app.js
angular.module('MyApp', [])
.filter('reverse',[function(){
return function(string){
return string.split('').reverse().join('');
}
}])
I've tried to change the node version too, but it isn't worked.
The solution was put the angular imports before the app files like this:
files: [
'node_modules/angular/angular.js',
'node_modules/angular/angular.min.js',
'node_modules/angular-mocks/angular-mocks.js',
'app/*.js',
'tests/*.js'
]

Jasmine return TypeError: module is not a function

I have a problem with Karma and Jasmine test for AngularJS controller. I read a lot about this subject on StackOverflow and I'm really sure that load files order is OK, but all time I get the error:
TypeError: module is not a function
at Suite.<anonymous> (/app/karma/developers/developer.ut.js:6:16)
at /app/karma/developers/developer.ut.js:1:1
My karma.config.js:
module.exports = function(config) {
config.set({
basePath: './app',
files: [
'bower_components/angular/angular.js',
'bower_components/angular-mocks/angular-mocks.js',
'bower_components/angular-route/angular-route.js',
'app.js',
'developers/*.js',
'karma/developers/*.js',
'karma/*.js'
],
autoWatch: true,
frameworks: ['jasmine'],
browsers: ['Chrome'],
plugins: [
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-jasmine',
'karma-junit-reporter'
],
junitReporter: {
outputFile: 'test_out/unit.xml',
suite: 'unit'
}
});
};
And my developer.ut.js:
describe('DeveloperCtrl', function () {
var $rootScope;
var $controller;
var YourControllerHere;
beforeEach(module('myApp.developers'));
beforeEach(inject(function($injector) {
$rootScope = $injector.get('$rootScope');
$controller = $injector.get('$controller');
$scope = $rootScope.$new();
}));
beforeEach(inject(function($controller) {
YourControllerHere = $controller("DeveloperCtrl");
}));
it('jak dziaƂa', function () {
expect(YourControllerHere.message).toBe("Hello");
});
});

jasmine error when I inject a Factory

I ran a jasmine test over angular js, and i get the next error:
PhantomJS 2.1.1 (Linux 0.0.0) test_servicioCalculadora should provide
a version FAILED
/home/ivan/workspace/mobile.trackphone/www/lib/ionic/js/ionic.bundle.js:13218:53
forEach#/home/ivan/workspace/mobile.trackphone/www/lib/ionic/js/ionic.bundle.js:9168:24
loadModules#/home/ivan/workspace/mobile.trackphone/www/lib/ionic/js/ionic.bundle.js:13178:12
createInjector#/home/ivan/workspace/mobile.trackphone/www/lib/ionic/js/ionic.bundle.js:13104:22
workFn#/home/ivan/workspace/mobile.trackphone/www/lib/angular-mocks/angular-mocks.js:3074:60
loaded#http://localhost:9876/context.js:151:17
I tried to change the routes, inject other service, and it's not working too
I ran other case like
it("compara un valor con otro", function () {
var pi = 3.1415926,
e = 2.78;
expect(e).toBeLessThan(pi);
expect(pi).not.toBeLessThan(e);
});
and this's working fine.
This is my test file
describe("test_servicioCalculadora", function () {
var calcu;
beforeEach(module('starter'));
it('should provide a version', inject(function(version) {
expect(version).toEqual('v1');
}));
});
my index.js is
var app = angular.module('starter', ['ionic', 'LocalStorageModule', 'btford.socket-io', 'angularMoment', 'ngCordova', 'ngAudio']);
app.value('version', 'v1');
my karma.config.js
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'../www/lib/ionic/js/ionic.bundle.js',
'../www/lib/angular-mocks/angular-mocks.js',
'../www/js/index.js',
'../tests/**/*-test.js'
],
exclude: [
],
preprocessors: {
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_ERROR,
autoWatch: true,
browsers: ['PhantomJS'],
singleRun: false,
concurrency: Infinity
})
};
You are trying to inject a value. Should be a service or a factory.
e.g.
beforeEach(module('some.service', function($provide){
var log = {
info: function(data){
console.log(data);
}
}
$provide.value('$log', log);
});
beforeEach(inject(function(_serviceName_){
serviceName = _serviceName_;
}));
it("Actual test", function(){
serviceName.performAction();
});
See the example, first is the module where you can set some values. Then is the service or factory at the end the test.
This mean that the value of log will be injected on serviceName when is used on the actual test.
Hope this help to clarify.

requirejs throws a 404 trying to load a file from karma runner

I am trying to load a test helper module using requirejs, but it fails even when it has been already loaded as a dependency at the start of karma run, and I can't figure out what's the problem, I always get
There is no timestamp for /base/spec/helpers/testHelpers!'
Tests run fine, inside them I require any module of the app without problem, it only fails when I require specifically something from spec folder.
I have checked all karma related questions and none of them apply to these case.
My karma.conf file:
module.exports = function (config) {
'use strict';
config.set({
basePath: '',
frameworks: ['jasmine', 'requirejs'],
files: [
'bootstrapTests.js',
{
pattern: 'app/**/*.js',
included: false
},
{
pattern: 'entities/**/*.js',
included: false
},
{
pattern: 'config/**/*.js',
included: false
},
{
pattern: 'libs/**/*.js',
included: false
},
{
pattern: 'spec/**/*Spec.js',
included: false
},
{
pattern: 'spec/helpers/**/*.js',
included: false
}
],
exclude: [
'bootstrap.js',
'bootstrap.built.js'
],
preprocessors: {
'app/**/*.js': ['coverage'],
'entities/**/*.js': ['coverage']
},
coverageReporter: {
reporters: [
{
type: 'text-summary'
}
]
},
reporters: ['progress', 'coverage'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['PhantomJS'],
singleRun: false
});
};
My bootstrapTests.js file:
var tests = [];
for (var file in window.__karma__.files) {
if (window.__karma__.files.hasOwnProperty(file)) {
// Add all spec files and helpers
if (/spec\/.+.js$/.test(file)) {
tests.push(file);
}
}
}
require.config({
baseUrl: '/base',
paths: {
'backbone': 'libs/backbone',
'marionette': 'libs/backbone.marionette',
'jquery': 'libs/jquery-2.1.1',
'json2': 'libs/json2',
'underscore': 'libs/underscore',
'twig': 'libs/twig',
'editor': 'app/editor',
'widgets': 'app/widgets',
'menu': 'app/menu',
'helpers': 'spec/helpers'
},
map: {
'*': {
'jquery': 'config/jquery/jqueryPrivate'
},
'config/jquery/jqueryPrivate': { 'jquery': 'jquery' }
},
deps: tests,
callback: window.__karma__.start
});
so in my tests,
define([
'app/app',
'backbone',
'editor/editorController',
'editor/editorApp',
], function (
myApp,
Backbone,
editorController
) {
'use strict';
describe('editorApp', function () {
.....
works like a charm, but when I try
define([
'app/common/routerUtilities',
'backbone',
'helpers/testHelpers'
], function (
routerUtilities,
Backbone,
testHelpers
) {
'use strict';
describe('routerUtilities', function () {
...
it fails trying to fetch testHelpers, always get the error even when the module is already loaded. I tried specifying the path in all possible ways besides the shortened one: spec/helpers/testHelpers, /base/spec/helpers/testHelpers, /spec/helpers/testHelpers, ../../helpers/testHelpers, etc...
The file is included in tests array as a dependency (checked), so it's loaded (checked with console.log) along my tests and other test setup modules:
LOG: ['/base/spec/app/appSpec.js',
'/base/spec/app/common/routerUtilitiesSpec.js',
'/base/spec/app/editor/EditorLayoutViewSpec.js',
'/base/spec/app/editor/editorAppSpec.js',
'/base/spec/app/editor/editorControllerSpec.js',
'/base/spec/app/menu/menuControllerSpec.js',
'/base/spec/helpers/envSetup.js',
'/base/spec/helpers/testHelpers.js']
I've checked that is included in window._ karma _.files as well (edited for brevity):
LOG: Object{
/base/bootstrapTests.js: 'c389a1d36d1c48f2879d434b10fd5a25b6b07758',
/base/app/app.js: '7ad39554809146effd20dd1db908fc068f8119ba',
/base/app/common/routerUtilities.js: '4da0e1d1794cccc727b544cacbc6d672c0d9965a',
...
/base/config/marionette/renderer.js: '34a5e729f6133aa13841c5e949307cd437ca331b',
/base/config/marionette/templateCache.js: '9f1901d4c6f43f5f90dadacb1c4ac179efd14b15',
/base/spec/app/appSpec.js: 'e01f4fea3533e25cfcd4f7621e1c1c5559e0eed8',
/base/spec/app/common/routerUtilitiesSpec.js: 'a06b9793a635633d053142dff24d1ba4427dd365',
/base/spec/app/editor/EditorLayoutViewSpec.js: 'a24c7e8742e38b86d626bd6f3e45baacfa6af5eb',
/base/spec/app/editor/editorAppSpec.js: '800c0e8e82840ebd0d1af07c3ec4556a24ee0b04',
/base/spec/app/editor/editorControllerSpec.js: 'd2e259a477da85b6a2f742f5c6c3a4a34b7e340b',
/base/spec/helpers/envSetup.js: '297aa1e59477d967aa210bece1726e8a372cb630',
/base/spec/helpers/testHelpers.js: '5266065d344ca69f8f5980db16bf6d131492ebd0'
}
The content of spec/helpers/testHelpers.js is:
define([
'backbone'
], function (
Backbone
) {
'use strict';
var testHelpers = {
setupRoutingTest: function () {
Backbone.history.start();
Backbone.history.navigate('');
},
teardownRoutingTest: function () {
Backbone.history.navigate('');
Backbone.history.stop();
}
};
return testHelpers;
});
My folder structure is:
|-app
|---common
|---editor
|---menu
|---widgets
|-config
|---jquery
|---marionette
|-entities
|-features
|-gruntTasks
|---lib
|-spec
|---app
|-----common
|-----editor
|-----menu
|-----widgets
|---entities
|---helpers
|-tmp
Hi it looks like the karma-requirejs doesn't like the resources to be loaded into the tests array.
Try to modify the code to exclude the helper files and it could help
var tests = [];
for (var file in window.__karma__.files) {
if (window.__karma__.files.hasOwnProperty(file)) {
// Add all spec files and helpers
if (/spec\/.+.js$/.test(file)) {
tests.push(file);
}
}
}
This drove me a little nuts a while back. Make sure you're using karma-requirejs, not just requirejs.
https://www.npmjs.org/package/karma-requirejs
On that note, don't also load the production version of requirejs.

'undefined' is not an object (evaluating 'app.register.service') when using requirejs, angularamd and karma

In our angularjs project, we are using requirejs + angularAMD to manage dependencies. The application works fine, but we're having problems when running the jasmine tests using karma.
This is the error:
TypeError: 'undefined' is not an object (evaluating 'app.register.service')
at /home/bcatarino/Projects/spr/target-grunt/js/app/model/PressRelease.js:3
It seems that our app is not correctly injected into our test.
The source code for the test:
'use strict';
define(['angularAMD', 'pressRelease'], function(angularAMD, pressRelease) {
describe('PressReleaseModel test', function () {
var scope, pressReleaseModel;
var inject = angularAMD.inject;
inject(function (pressRelease) {
pressReleaseModel = pressRelease;
});
it('Should add a non-existing recipient', function(pressRelease) {
expect(pressReleaseModel.get().recipients.length, 0);
});
});
});
PressRelease is coded like this:
define([ 'app', 'angularAMD' ], function(app, angularAMD) {
app.register.service('pressRelease', function() {
//Stuff going on here
} );
});
So this is where app.register is undefined and we can't figure out why.
As requested, here's the karma.conf:
module.exports = function(config) {
config.set({
basePath: '../../../',
files: [
{pattern: 'js_components/angular/angular.js', watched: false, included: false},
{pattern: 'js_components/angular-mocks/angular-mocks.js', included: false},
{pattern: 'js_components/angularAMD/angularAMD.js', included: false},
{pattern: 'js_components/angular-ui-router/release/angular-ui-router.min.js', included: false},
{pattern: 'js_components/angular-ui-utils/ui-utils.js', included: false},
{pattern: 'js/test/test-app.js', watched: true, included: false},
{pattern: 'js/app/model/PressRelease.js', watched: true, included: false},
{pattern: 'js/test/model/PressReleaseModelSpec.js', watched: true, included: false},
'js_components/requirejs/require.js',
'js/test/test-main.js'
],
exclude: [],
plugins: [
'karma-jasmine',
'karma-phantomjs-launcher',
'karma-chrome-launcher',
'karma-requirejs'
],
frameworks: ['jasmine', 'requirejs'],
junitReporter: {
outputFile: 'karma-test-results.xml',
suite: ''
},
port: 9876,
runnerPort: 9100,
browsers: ['PhantomJS', 'Chrome'],
autoWatch: true,
preprocessors: {
'template/**/*.html': ['html2js']
},
ngHtml2JsPreprocessor: {
// strip this from the file path
stripPrefix: 'web',
moduleName: 'templates'
},
logLevel : config.LOG_INFO
})
};
Anyone has any ideas? We're following this as example, but we're not finding the answer:
https://github.com/marcoslin/angularAMD
Thanks
I solved it by removing AngularAMD from unit tests. I created a bridge that redirects app.register.method to app.method where app is an Angular module.
define([
'angularMocks',
'angular'
], function () {
'use strict';
var myapp = angular.module('SPR', []);
myapp.register = {};
var enhanceModule = function (method) {
var register = myapp.register;
register[method] = angular.bind(myapp, myapp[method]);
};
angular.forEach([
'controller',
'directive',
'filter',
'factory',
'service',
'constant',
'value',
'animation']
, enhanceModule);
console.info('Enhanced angular.module');
return angular.module('SPR');
});
This is the test:
define(['angularMocks', 'app', 'js/app/model/PressRelease'], function (mocks) {
describe('Press Release model', function () {
var service;
beforeEach(mocks.module('SPR'));
beforeEach(mocks.inject(function (PressRelease) {
service = PressRelease;
}));
it('should do something', function () {
var res = service.serviceCall();
expect(res).toBe(1);
});
});
});
I never managed to get ngScenario to work with angularAMD. I had to use Protractor, the new standard for AngularJS E2E testing, for angularAMD.
Here is the Protractor spec file:
https://github.com/marcoslin/angularAMD/blob/master/test/e2e/www.spec.js
You can also find some more detail about E2E testing and angularAMD at:
https://github.com/marcoslin/angularAMD/issues/20
The Travis is reporting build failure right now but the test runs fine in my local machine.

Categories