Unit Testing an Angular Service using Karma and Jasmine - angularjs

I am new to angular and TDD in angular
I want to test drive a service, but before that wanted to understand the flow. I am having a few issues. I keep getting this error
Firefox 47.0.0 (Windows 10 0.0.0) ERROR
Error: [$injector:nomod] http://errors.angularjs.org/1.5.7/$injector/nomod?p0=myApp
at C:/domain/domain/test/unitTest/spec/client/lib/angular.min.js:6
My app.js file is as follow
angular.module('myApp', [
'smart-table',
'ngRoute',
'ng-bs3-datepicker',
'angucomplete-alt',
'angular-loading-bar',
'checklist-model',
'ngFileUpload',
'ui.bootstrap'
])
.config(['$locationProvider', '$routeProvider', function ($locationProvider, $routeProvider) {
//some code here
}])
My services.js code is as follows
angular.module('myApp')
.service('usersLocationService', function () {
this.SetLocation = function (place) {
var address = {};
//some code here
return address;
};
}
My karma.conf.js file is as follows
// Karma configuration
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: [
'test-main.js',
'test/unitTest/spec/client/lib/angular.min.js',
'test/unitTest/spec/client/lib/angular-mocks.js',
'public/Controllers/**/*.js',
'public/Controllers/subDomain/**/*.js',
'https://code.jquery.com/jquery-1.11.2.min.js',
'test/unitTest/spec/client/**/*.js'
],
// list of files to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
},
// 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_INFO,
// 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: ['Firefox'],
// 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
})
}
And finally my unitTest case code is
"use strict";
describe('Test Suite for UserLocationService', function () {
beforeEach(angular.module.mock('myApp'));
beforeEach(inject(function (_usersLocationService_) {
this.sut = _usersLocationService_;
}));
it('Should return the address from the google location place', function() {
var place = {};
var data = this.sut.SetLocation(place);
console.log(data);
});
});

There is no angular.module.mock function. It is
angular.mock.module('myApp')

Related

Jasmine unit testing: inject http service

I have the next service "IrChartService":
public getDataAfterUpdate(entityId: number, timestamp: number) {
var deferred = this.$q.defer();
var requestUrl = this.IrChartData + '/datasequences/entities/' + entityId + '/ir?timestamp=' + timestamp;
this.$http.get(requestUrl).then((result) => {
deferred.resolve(result.data);
});
return deferred.promise;
}
That service is used in a controller.
Here I have the test file:
/* Test Code */
describe('IrChartService', function () {
var IrChartService, $httpBackend, $q, IrChartData;
beforeEach(function(){
angular.module('genscape.rt.irchart')
});
beforeEach(inject(function(_$httpBackend_, _IrChartService_, _$q_, _IrChartData_) {
IrChartService = _IrChartService_;
$httpBackend = _$httpBackend_;
$q = _$q_;
IrChartData = _IrChartData_;
}));
it('is defined', function () {
console.log('def');
expect(IrChartService).toBeDefined();
});
it('should call the backend testurl', function() {
var returnData = {
"ImagePath": "/20160406/167/167_20160406_065626.jpg",
"ConfidenceValue": 4
};
console.log('test');
//7. expectGET to make sure this is called once.
$httpBackend.expectGET("../mock/chartData.specs.json").respond(returnData);
$httpBackend.flush();
});
});
It return me errors like:
Error: [$injector:unpr] http://errors.angularjs.org/1.4.0-rc.2/$injector/unpr?p0=IrChartServiceProvider%20%3C-%20IrChartService
TypeError: Cannot read property 'expectGET' of undefined
Expected undefined to be defined.
Can you help me, please? Thanks!
Update:
// Karma configuration
// Generated on Wed May 20 2015 15:52:13 GMT-0400 (Eastern Daylight Time)
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'],
plugins: [
'karma-chrome-launcher',
'karma-jasmine',
'karma-html-reporter',
'karma-ng-html2js-preprocessor'
],
// list of files / patterns to load in the browser
files: [
'Scripts/angular.min.js',
'Scripts/angular-mocks.js',
'Scripts/genscape.common.js',
'app/template.module.js',
'app/app.module.js',
'app/templates.js',
'app/app.widget.service.js',
'app/IRchart/IRchart.service.js',
'app/IRchart/IRchart.controller.js',
'app/IRchart/IRchart.directive.js',
'app/IRchart/IRchart-error.directive.js',
'app/IRchart/IRchart-popup/IRchart-popup.controller.js',
'app/IRchart/IRchart-player/IRchart-player.controller.js',
'app/IRchart/IRchart-player/IRchart-player.directive.js',
'test/specs/specs.js',
// fixtures
{ pattern: 'test/mock/*.json', watched: true, served: true, included: false }
],
preprocessors: {
'**/*.html': ['ng-html2js']
},
ngHtml2JsPreprocessor: {
// we want all templates to be loaded in the same module called 'templates'
moduleName: 'genscape.rt.irchart'
},
// list of files to exclude
exclude: [
],
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'html'],
// 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_INFO,
// 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: ['Chrome'],
browsers: ['Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false
});
};

How to test html tags in karma test

I want to test my html tags(text,div,span,etc...)
I am using angularjs,karma with jasmine framework.
This my karma file, here i include ng-html2js preprocess.
// Karma configuration
// Generated on Tue Jan 26 2016 21:38:16 GMT+0530 (India Standard Time)
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'],
// list of files / patterns to load in the browser
files: [
'../app/js/base.js',
'../global_URL.js',
'../app/**/*.html',
'bower_components/angular-mocks/angular-mocks.js',
'../app/js/app.js',
'test/spec/**/*.js',
'../app/**/*.json'
],
// list of files to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'../app/**/*.html': ['ng-html2js']
},
ngHtml2JsPreprocessor: {
moduleName: 'templates'
},
// 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_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome'],
plugins: [
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-jasmine',
'karma-phantomjs-launcher',
'karma-ng-html2js-preprocessor'
],
// 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
})
}
For getting html page i am using httpBackend, my test file like this.
'use strict';
describe('Login Controller', function () {
// load the controller's module
var MainCtrl,
httpBackend,
templateHtml
formElem,
form,
scope;
beforeEach(module('test'));
beforeEach(module('templates'));
beforeEach(module('ngMockE2E'));
//beforeEach(module('sample',['ngMock']));
// Initialize the controller and a mock scope
beforeEach(inject(function ($rootScope, $controller,$compile,$httpBackend,$templateCache) {
scope = $rootScope.$new();
httpBackend = $httpBackend
MainCtrl = $controller('TestController', {
$scope: scope,
});
templateHtml = httpBackend.expectGET('app/admin/login.html').respond([]);
console.log(templateHtml)
formElem = angular.element("<div>test</div>")
$compile(formElem)(scope)
form = scope.form
scope.$apply()
}));
it('should not allow an invalid `width`', function() {
expect(form).toBeDefined();
});
});
Here i print my html page in console, but it's wrote as undefined.
How can i inject my html pages in karma and how can i test html tags.
Please help me, thanks in advance.
to preload html we use the following karma.conf.js ...
'use strict';
module.exports = function (config) {
config.set({
basePath: './',
browsers: ['PhantomJS'],
frameworks: ['jasmine'],
reporters: ['mocha', 'coverage'],
singleRun: true,
preprocessors: {
'src/**/!(*spec)*.js': ['coverage'],
'dest/**/*.html': ['ng-html2js']
},
ngHtml2JsPreprocessor: {
stripPrefix: 'dest/',
moduleName: 'ngHtmlFiles'
},
coverageReporter: {
type: 'html',
dir: 'coverage'
},
files: [
'dest/vendor.min.js',
'bower_components/angular-mocks/angular-mocks.js',
'src/**/*.js',
'dest/**/*.html'
]
});
};
then in each test ...
beforeEach(module('ngHtmlFiles'));
This will preload the HTML.
However, we do this for a totally different reason to you, namely to prevent httpBackend failing expectations when requests for HTML files are made.
I personally would use protractor E2E testing to test the UI. I believe unit tests should be limited to testing controller / service code only.

How to remove module not found error in angular?

I make a simple example of controller here .
http://plnkr.co/edit/dplJ6sf4kgiwJ5pXu4GE?p=preview
and I want to test the controller .I am able to test my controller online
Here is my code to test my controller online
http://plnkr.co/edit/xzvhXHPoUdulOM9clOkQ?p=preview
But when I try to run that same work on my computer my test case are fail
I am getting error this
Module 'app.home' 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.
Here is my computer code.
https://dl.dropbox.com/s/no901z41bza7osm/SimpleDemo.zip?dl=0
Please run npm install to add dependency .
Here is my karma.conf.js file
// Karma configuration
// Generated on Fri Dec 18 2015 19:53:32 GMT+0530 (IST)
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'],
// list of files / patterns to load in the browser
files: [
'bower_components/angular/angular.js' ,
'bower_components/jquery/dist/jquery.js' ,
'bower_components/angular-ui-router/release/angular-ui-router.js' ,
'bower_components/angular-mocks/angular-mocks.js' ,
'bower_components/angular-resource/angular-resource.js' ,
'app/*.js',
'app/**/*.js',
'app/**/*.html',
'test/**.js'
],
// list of files to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'app/**/*.html':['ng-html2js']
},
ngHtml2JsPreprocessor:{
moduleName:'templates'
},
// 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_INFO,
// 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: ['Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultanous
concurrency: Infinity
})
}
here is my code testing
(function(){
'use strict'
describe('http controller test', function() {
var $rootScope,
$scope,
controller,
$q,
$httpBackend;
beforeEach(function() {
module('app');
inject(function($injector) {
$rootScope = $injector.get('$rootScope');
$scope = $rootScope.$new();
controller = $injector.get('$controller')('homeCntrl', {
$scope: $scope
})
})
})
describe('Init value', function() {
it('check name value', function() {
expect(controller.message).toBeUndefined();
})
})
it('it should be true', function() {
expect(true).toBeTruthy();
})
})
})()
any update ?how to do testing of controller?
update 1
when I write like that it is not working ...check these file
'app/**/*.js',
'app/*.js',
'app/home/controller/*.js',
'app/**/*.html',
'test/**.js'
whole code
files: [
'bower_components/angular/angular.js' ,
'bower_components/jquery/dist/jquery.js' ,
'bower_components/angular-ui-router/release/angular-ui-router.js' ,
'bower_components/angular-mocks/angular-mocks.js' ,
'bower_components/angular-resource/angular-resource.js' ,
'app/**/*.js',
'app/*.js',
'app/home/controller/*.js',
'app/**/*.html',
'test/**.js'
],
but when I write like that it work perfectly why ?
files: [
'bower_components/angular/angular.js' ,
'bower_components/jquery/dist/jquery.js' ,
'bower_components/angular-ui-router/release/angular-ui-router.js' ,
'bower_components/angular-mocks/angular-mocks.js' ,
'bower_components/angular-resource/angular-resource.js' ,
'app/home/*.js',
'app/app.js',
'app/home/controller/*.js',
'app/**/*.html',
'test/**.js'
],
Change homeCntrl to homecntrl
In your route.js in this line: controller:'homeCntrl as home'

angular Failed to instantiate module myModule issue

I am configuring my Karma amd mocha framework with grunt in my project.
When I am running karma start I am getting below mentioned error.
Uncaught Error: [$injector:modulerr] Failed to instantiate module myModule due to: Error: [$injector:nomod] Module 'myModule' is not available!
My controller:
(function () {
var module = angular.module('myModule',[]);
module.controller('myCtrl', function($scope, $q, $rootScope, templateValuesSrv) {
function() {
var self = this;
self.firstName = '';
self.lastName = '';
self.getFullName = function() {
return self.firstName + ' ' + self.lastName;
};
return self;
}
});
})();
My Controller Spec:
describe('myCtrl', function() {
beforeEach(module('myModule'));
describe('getFullName()', function() {
it('should handle names correctly', inject(function($controller) {
var myController = $controller('myCtrl');
myController.firstName = 'George';
myController.lastName = 'Harrison';
myController.getFullName().should.equal('George Harrison');
}));
});
});
My Karma.conf.js
// Karma configuration
// Generated on Fri Nov 27 2015 11:48:47 GMT+0530 (India Standard Time)
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: ['mocha', 'chai'],
// list of files / patterns to load in the browser
files: [
'bower_components/angular/angular.js',
'bower_components/angular-mocks/angular-mocks.js',
'test/specs/*.js',
//'test/*.js'
],
// list of files to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
},
// 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_INFO,
// 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', 'Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultanous
concurrency: Infinity
})
}
Please suggest what I am missing.
Before the specs you should add the js files that you want to test.
// Karma conf
files: [
'bower_components/angular/angular.js',
'bower_components/angular-mocks/angular-mocks.js',
'src/**/*.js',
'test/specs/*.js',
//'test/*.js'
],
If you use a bundler like webpackt or bower then you could require then on each spec

Angular JS tests with Jasmine and PhantomJS, 0 Error

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'],
// list of files / patterns to load in the browser
files: [
'../scripts/bower_components/angularjs/angular.js',
'../scripts/bower_components/angular-mocks/angular-mocks.js',
'../scripts/app.js',
'../scripts/11.js',
'../scripts/controllers/*.js',
'../scripts/directives/*.js',
'../scripts/services/*.js',
'controllers/controllersTests.js',
],
// list of files to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
},
// 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_INFO,
// 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', 'PhantomJS_custom'],
customLaunchers: {
'PhantomJS_custom': {
base: 'PhantomJS',
options: {
windowName: 'my-window',
settings: {
webSecurityEnabled: false
},
},
flags: ['--load-images=true'],
debug: false
}
},
phantomjsLauncher: {
// Have phantomjs exit if a ResourceError is encountered (useful if karma exits without killing phantom)
exitOnResourceError: true
},
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false
})
}
I need to test code of controllers, but i can't see right result, code below:
"slide" array length = 4; but in test i write "toBe(2)" and i see:
PhantomJS 1.9.8 (Linux 0.0.0): Executed 0 of 0 ERROR (0.035 secs / 0 secs)
Why i see 0 errors, if I expect 2, but array length is 4 ???
app.controller('mainCtrl',['$scope', function($scope){
$scope.slide = [1, 2, 3, 4];
}]);
describe('Tests Controllers', function() {
beforeEach(module('app'));
var $controller;
beforeEach(inject(function(_$controller_, $rootScope){
$controller = _$controller_;
it('check slides length, it should be 4', function() {
var $scope = {};
var controller = $controller('mainCtrl', { $scope: $scope });
expect($scope.slide.length).toBe(2);
});
}));
});
When Karma can't find your tests and displays Executed 0 of 0 ERROR, the most popular reasons which lead to this behavior are:
bad path to a test file/folder in karma.conf.js in the files:[] option
missing specs (it blocks) in the test file/folder, so Karma has nothing to execute. It may occur also if specs are placed inappropriately within a test file, like in your case you've put it inside beforeEach, but Jasmine does not support it. The idea is to put them on the same level. it spec can live separately in the global scope or right within describe suite blocks.

Resources