Understanding AngularJS testing - angularjs

I seem to be unable to wrap my head around the concept of testing AngularJS applications.
I use PHPstorm as my IDE and have successfully installed node.js aswell as karma through node.
I have then created a karma.config file:
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'js/angular.js',
'js/va.angular.js',
'test/**/**/*Spec.js'
],
exclude: [
],
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['C:/Program Files (x86)/Google/Chrome/Application/chrome.exe'],
captureTimeout: 60000,
singleRun: false
});
};
I have also created a test file:
// mainSpec.js
describe('controllers', function(){
beforeEach(angular.module('va'));
it('should friggin test something', inject(function() {
var x = 5;
expect(x.toBe(5));
}));
});
However, as i try to run my test, it fails due to:
TypeError: Object #<Object> has no method 'apply'
TypeError: Object 5 has no method 'toBe'
Now i have 2 questions:
What am i doing wrong here?
Where does the karma stuff get the jasmine stuff from? To me it looks like it can't get it.

Make sure you're including the angular-mocks.js module in your list of files to load.
When you specify frameworks: ['jasmine'] in the karma config, it includes jasmine so there's no need to include it yourself.
As for your error,
expect(x.toBe(5))
should be:
expect(x).toBe(5)

Related

Angular.js injector error doesn't give any hints about missing dependencies in Karma test

I'm trying to create few simple tests for my Angular.JS app, but unfortunately, I can't resolve missing dependencies due to very short output from Angular / Karma (?)
My Karma config looks as follows:
module.exports = function (config) {
config.set({
basePath: '',
singleRun: true,
autoWatch: false,
frameworks: ['jasmine'],
browsers: ['PhantomJS'],
preprocessors: {
'./src/app/myApp.app.js': ['babel']
},
files: [
'./node_modules/angular/angular.js',
'./node_modules/angular-mocks/angular-mocks.js',
'./src/app/myApp.app.js',
'./test.js'
],
plugins: [
'karma-mocha-reporter',
'karma-jasmine',
'karma-babel-preprocessor',
'karma-phantomjs-launcher'
],
babelPreprocessor: {
options: {
presets: ['env'],
sourceMap: 'inline'
},
sourceFileName: function (file) {
return file.originalPath;
}
},
reporters: ['mocha']
});
}
What I'm doing here is basically including angular, angular-mocks, entry module for my app and one file with tests. Of course, some dependencies are missing now, but I'd like to add only required ones (and learn about missing steps after karma start).
Unfortunately, after running karma start I can only see that test has failed, and that's all - nothing more (for example, at runtime you can see 'rich' error message in browser's console, based on which you can include missing dependencies). Take a look at this error:
x it should do something funny
PhantomJS 2.1.1 (Mac OS X 0.0.0)
node_modules/angular/angular.js:4693:53
forEach#node_modules/angular/angular.js:325:24
loadModules#node_modules/angular/angular.js:4653:12
createInjector#node_modules/angular/angular.js:4575:30
WorkFn#node_modules/angular-mocks/angular-mocks.js:3120:60
And that's all. If I include minified version of Angular, I see a browser-like error message, based on which I can add required dependencies. With non-minified version, it's working like I've described. So my question is - how can I make error messages rich in karma tests?

Karma Jasmine tests all fail after integrating ui-router

I have a lot of tests in this app that were passing, but after integrating ui-router, every one of them fails. I am getting errors like TypeError: undefined is not an object (evaluating '$httpBackend.verifyNoOutstandingExpectation'). and TypeError: undefined is not an object (evaluating '$rootScope.$digest'). Anything that gets injected in the tests no longer works once I do the integration.
The tests only fail if I inject the $stateProvider, $stateParams or $urlRouteProvider. If I don't inject those, then they pass.
Is there some sort of configuration that I need? Does anyone know why all of a sudden all of the previous injections are non-existent?
Error Example
forEach#app/vendor/angular/angular.js:403:24
loadModules#app/vendor/angular/angular.js:4880:12
createInjector#app/vendor/angular/angular.js:4802:30
WorkFn#app/vendor/angular-mocks/angular-mocks.js:3163:60
app/vendor/angular/angular.js:4921:53
TypeError: undefined is not an object (evaluating '$rootScope.$digest') in app/core/test/sideBarDirTest.js (line 63)
app/core/test/sideBarDirTest.js:63:23
Karma Config
basePath: '',
frameworks: ['jasmine'],
files: [
'app/vendor/jquery/dist/jquery.js',
'app/vendor/angular/angular.js',
'app/vendor/angular-resource/angular-resource.js',
'app/vendor/angular-mocks/angular-mocks.js',
'app/core/app.js',
'app/core/envConfig.js',
'app/core/sideBarDir.js',
'app/core/app.js',
'app/core/test/*.js',
'**!/!*.html',
{pattern: 'app/core/**/*.json', watched: true, served: true, included: false}
],
exclude: [
'app.js',
'**/gulpfile.js'
],
reporters: ['progress', 'coverage', 'junit'],
preprocessors: {
'app/**/*.html': ['ng-html2js'],
'app/core/**/!(*Test|*test).js': 'coverage',
},
ngHtml2JsPreprocessor: {
stripPrefix: 'app/',
moduleName: 'html'
},
junitReporter: {
outputFile: 'coverage/test-results.xml',
suite: ''
},
coverageReporter: {
type: 'lcov',
dir: 'coverage/'
},
port: 9876,
colors: true,
config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['PhantomJS'],
captureTimeout: 10000,
singleRun: true
I realized the root cause was just some missing modules. It seems as though my integration of ui-router required more files to be added to karma config than I thought.
When I asked this question, the error messages were very basic and that was what caused my headache. I fixed this problem by using Chrome as the browser to test with in the Karma config. This switch immediately showed me the issue. Apparently PhantomJS strips out/doesn't add the juicy parts of the error message(read: the actual Angular error).
So if you are randomly failing every test that used to pass, then I suggest that you switch to the Chrome browser to see if you aren't getting everything.

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.

Issue with angular.mock.inject method

I am using folloing jasmine test case
'use strict';
describe('companyService', function() {
var $httpBackend, companyService;
beforeEach(angular.mock.module('myApp'));
beforeEach(angular.mock.inject(function(_$httpBackend_ , _companyService_) {
$httpBackend = _$httpBackend_;
companyService = _companyService_;
}));
it('should return a promise for getCompany function', function() {
// expect(typeof companyService.getCompany('foobar').then).toBe('function');
});
});
i am getting the following error . as you can see above . i am not doing anything inside it block .
minErr/<#C:/Users/userone/Documents/myAppPkg/myApp/WebApiRole/bower_components/angular/angular.js:63:12
loadModules/<#C:/Users/userone/Documents/myAppPkg/myApp/WebApiRole/bower_components/angular/angular.js:4138:15
forEach#C:/Users/userone/Documents/myAppPkg/myApp/WebApiRole/bower_components/angular/angular.js:323:11
loadModules#C:/Users/userone/Documents/myAppPkg/myApp/WebApiRole/bower_components/angular/angular.js:4099:5
createInjector#C:/Users/userone/Documents/myAppPkg/myApp/WebApiRole/bower_components/angular/angular.js:4025:11
workFn#C:/Users/userone/Documents/myAppPkg/myApp/WebApiRole/node_modules/angular-mocks/angular-mocks.js:2425:44
irefox 38.0.0 (Windows 8.1): Executed 1 of 1 (1 FAILED) ERROR (0.251 secs / 0.008 secs)
I assume this issue comes because of the angular.mock.inject method i have been using . because the execution does not enter the following block
beforeEach(angular.mock.inject(function(_$httpBackend_ , _companyService_) {
$httpBackend = _$httpBackend_;
companyService = _companyService_;
}));
Karma.conf.js file
// Karma configuration
// Generated on Thu May 21 2015 16:24:51
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',
'node_modules/angular-mocks/angular-mocks.js',
'app/app.js',
'app/*.js',
'app/**/*.js',
'app/**/**/*.js',
'app/company/CompanyService.js',
'test/company/*.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
hostname: 'localhost',
port: 44555,
// 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
});
};
can any one help me out with this . ?
You should update the "karma-chrome-launcher" and "karma-firefox-launcher" in node_module.
This may be solve the issue.
npm install karma-chrome-launcher
npm install karma-firefox-launcher
If you think the issue because of "angular.mock.inject " then one can use inject function.
But I think your unit test script is not getting chance for loading and execution.So,this will not reason for above error.
Thanks.
I found out the solution for this problem. Turns out i have missed some dependencies in the karma.conf.js . When you missed dependencies , the $inject method does not get executed . What i did was , from the index.html , copied all the dependencies (from bower componants folder and node_modules folder) and put them in the karma.conf.js under files .
for example , i have copied all the file dependencies from index.html and put it under files
'bower_components/angular/angular.js',
'node_modules/angular-mocks/angular-mocks.js',
'bower_components/jquery/dist/jquery.js',
'bower_components/pnotify/pnotify.core.js',
'bower_components/pnotify/pnotify.buttons.js',
'bower_components/pnotify/pnotify.confirm.js',
'bower_components/pnotify/pnotify.desktop.js',
'bower_components/pnotify/pnotify.nonblock.js',
'bower_components/pnotify/pnotify.callbacks.js',
'bower_components/pnotify/pnotify.history.js',
'bower_components/pnotify/pnotify.reference.js',
'bower_components/jquery-ui/jquery-ui.min.js',
'bower_components/bootstrap/dist/js/bootstrap.js',
'js/fullcalendar.min.js',
'js/daterangepicker.min.js',
'bower_components/moment/moment.js',
'bower_components/moment-timezone/builds/moment-timezone-with-data-2010-2020.js',
'bower_components/angular-i18n/angular-locale_no.js',
'bower_components/ng-file-upload/angular-file-upload.js',
'bower_components/angular-ui-router/release/angular-ui-router.js',
'bower_components/angular-bootstrap/ui-bootstrap-tpls.js',
'bower_components/angular-translate/angular-translate.js',
'bower_components/angular-translate-loader-static-files/angular-translate-loader-static-files.js',
'bower_components/angular-pnotify/src/angular-pnotify.js',
'bower_components/angular-local-storage/angular-local-storage.js',
'bower_components/angular-loading-bar/build/loading-bar.min.js',
'bower_components/angular-moment/angular-moment.js',
'bower_components/angular-bootstrap-switch/dist/angular-bootstrap-switch.js',
'bower_components/bootstrap-switch/dist/js/bootstrap-switch.js',
'app/app.js',
'app/**/*.js',
'test/**/*Spec.js'

Karma to show Jasmine tested AngularJs code in browser

I have a working karma setup, which shows the test-results of my jasmine-tests in the console.
If I start the Jasmine SpecRunner.html I get the error "module is not defined" Therefore I added the angular-mock inside the SpecRunner-Header:
<script type="text/javascript" src='src/public/js/libs/angular/angular-mock.js'></script>
Here's my karma.config:
config.set({
basePath: '../..',
frameworks: ['jasmine'],
files: [
'host/test_app/lib/jasmine-2.0.0/jasmine.js',
'host/test_app/src/public/js/libs/angular/angular.min.js',
'host/test_app/src/public/js/libs/angular/angular-mock.js',
'host/test_app/spec/*.js',
'host/test_app/src/public/js/controller/*.js'
],
exclude: [ ],
preprocessors: { },
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome', 'Firefox'],
singleRun: false
});
Is there a way to make karma show the tests with jasmines specrunner?
try using an unminified angular.js instead of angular.min.js while debugging it would give you a more meaningful error.it worked to me before.
in addition to this, if your modules are injecting asynchronously you should move your angularjs to the top because karma is working like queue while injecting them into karma config file. if im wrong, please correct me.

Resources