How to inject ngRoute into Jasmine / Karma AngularJS unit test? - javascript

I'm trying to get a basic unit test example working. It all works fine with this app.js
var whapp = angular.module('whapp', [])
.filter('reverse',[function(){
return function(string){
return string.split('').reverse().join('');
}
}]);
and this spec.js
describe('Filters', function(){ //describe your object type
beforeEach(module('whapp')); //load module
describe('reverse',function(){ //describe your app name
var reverse, rootScope;
beforeEach(inject(function($filter){ //initialize your filter
reverse = $filter('reverse',{});
}));
it('Should reverse a string', function(){ //write tests
expect(reverse('rahil')).toBe('lihar'); //pass
});
});
});
with this karma files config
files: [
'node_modules/angular/angular.js',
'node_modules/angular-mocks/angular-mocks.js',
'node_modules/angular-mocks/angular-route/angular-route.js',
'node_modules/angular-mocks/angular-ui-router/release/angular-ui-router.js',
'app/js/*.js',
'tests/*.js'
]
The problem occurs when I try to inject ngRoute into my module in app.js like so
var whapp = angular.module('whapp', ['ngRoute'])
.filter('reverse',[function(){
return function(string){
return string.split('').reverse().join('');
}
}]);
In which case I get the following error in karma [UPDATE: this error occurs even if I don't load the angular-mock.js library into karma as shown above]
TypeError: undefined is not a constructor (evaluating 'reverse('rahil')') in tests/spec.js (line 9)
So... how do I inject ngRoute into spec.js correctly? I've tried a variety of things, none of which worked.

Apparently, you get this error because PhantomJS fails to instantiate your main Angular module whapp. One possible reason is, that the file node_modules/angular-mocks/angular-route/angular-route.js is missing.
Obviously, you are using npm to manage your dependencies. So try to replace your current file with:
node_modules/angular-route/angular-route.js
The same for the ui-route module:
node_modules/angular-ui-router/release/angular-ui-router.js
I hope this will help you.

Related

jasmine getFixtures is not a function

I'm developing some unitTests using Jasmine. I'm currently working on Windows8.1 and when I run my test I get following error message.
TypeError: jasmine.getFixtures() is not a function
This is the code that I'm using. I don't know what I must change in order to do this work.
Karma.conf.js
//More configuration entries
...........
files: [
// app-specific code
'src/app/app.js',
// 3rd-party resources
'node_modules/angular-mocks/angular-mocks.js',
// test files
'test/unit/**/*.js',
//fixture to serve mockData in Tests
{ pattern: 'test/unit/mock-data/*.json' }
]
Here is the piece of code from my test.
it('Should load my fixture', function(){
jasmine.getFixtures().fixturesPath = 'HpIpsUi/test/unit/mock-data';
var json = readFixtures('diagnostics.json');
var result = JSON.parse(json);
expect(result).toBeDefined();1
})
It's not recognizing my call to the function jasmine.getFictures().
Thank you for your help
Have you included the jasmine-query library? It's defined there, not in the jasmine library.
Said jasmine-query.js needs to be downloaded, and added as file, because it's not installable with npm yet.

Adding Webpack to an existing Angular app

I'm working on an existing (and working) Angular 1.5.5 app. It's very small and has a controller, a directive and a couple of services, all split into individual files.
I'd now like to move to Webpack and make the minimum number of changes to the app to support that. A lot of the Webpack/Angular demos I've found have been about creating a new Angular app with web pack built in from the start, but I don't want to rebuild the existing app, just make whatever changes are necessary to use a webpack-produced bundle. It's also using regular JS, whereas most of the tutorials I've seen are for ES6.
I've got grunt-webpack installed and working, it's creating the bundle.js file and I can see inside the bundle that it's pulling in Angular, Angular-aria and Angular-animate (my module dependencies)
However, when I run the site I see an error:
Uncaught TypeError: angular.module is not a function
My webpack task is as follows:
module.exports = {
dist: {
entry: './Static/js/Ng/app.js',
output: {
path: './Static/dist/js',
filename: 'bundle.js'
}
}
};
As I say, the actual Webpack bundling seems to be working as expected and creates the bundle.js file.
The main entry file (app.js) is as follows:
(function () {
'use strict';
var angular = require('../vendor/angular.js');
var ngAria = require('../vendor/angular-aria.js');
var ngAnimate = require('../vendor/angular-animate.js');
angular.module('app', [ngAria, ngAnimate]);
}());
If I log out the angular variable in this file, it's just an empty object, even though I can see the Angular source in the bundle.
What am I missing?
You probably shadow the global angular property by your local var angular variable. Try this:
(function () {
'use strict';
require('../vendor/angular.js');
require('../vendor/angular-aria.js');
require('../vendor/angular-animate.js');
angular.module('app', [ngAria, ngAnimate]);
}());

Unknown proider error with karma jasmine unit tests

I have a unit test that is created with the Jasmine framework. When I put a single test specification in the describe block I get a pass in the karma console. If I copy that describe block with the test in it ( the it(); ) then I suddenly start getting problems with dependencies that the module uses.
In the console I get errors around unknown providers.
Here is my simple test:
describe('service definition tests', function () {
it('should be defined', function () {
expect(sut).toBeDefined();
});
});
and that passes okay. If I copy this block I get an error about dependencies. Which is strange as I've already proved that I can test the 'sut' is defined in the first test.
One thing to note is that I have a beforeEach block that loads the module and provides a dependency and it is this dependency that errors when I've duplicated the test. Here is the beforeEach:
var mockConfig = {};
beforeEach(function () {
module('app');
module(function ($provide) {
$provide.value('myConfig', mockConfig);
});
});
the problem has to be something to do with this beforeEach being as the error I get is about the myConfig dependency.
Here is the error:
uncaught Error: [$injecor:unpr] Unknown provider: myConfigProvider <- myConfig <- authorisation
http://errors.angularjs.org/1.4.6/$injector/unpr?p0=myConfiProvider
I managed to resolve this issue by creating a dummy implementation of myConfig factory so that the test files used this.
angular.module('app').factory('myConfig', function() {
var env = 'test';
return {
env: env
}
});
This code lives in a js file that is loaded with the rest of the tests.

Error while requiring external library with browserify (this = undefined)

I'm trying to require the library Chart.js with Browserify (tbh it's development environment with gulp, browserify and some other stuff that I barely know how it works togheter):
'use strict';
var angular = require('angular');
require('angular-ui-router');
require('./templates');
require('./controllers/_index');
require('./services/_index');
require('./directives/_index');
window.gauge = require('./vendors/gauge');
//this is what i'm trying to require
window.chartjs = require('./vendors/chart');
angular.element(document).ready(function() {
var requires = [
'ui.router',
'templates',
'app.controllers',
'app.services',
'app.directives'
];
window.app = angular.module('app', requires);
angular.module('app').constant('AppSettings', require('./constants'));
angular.module('app').config(require('./routes'));
angular.module('app').config(require('./PostFix'));
angular.module('app').run(require('./on_run'));
angular.bootstrap(document, ['app']);
});
Tbh it did work well with window.gauge = require('./vendors/gauge'); but when I require vendors/chart.js it throws this error:
undefined // chart.js:4
Uncaught TypeError: Cannot read property 'Chart' of undefined // chart.js:4
And here is those lines in the chart.js file:
(function(){
"use strict";
console.log(this); <------ outputs the "undefined"
var root = this,
previous = root.Chart; <----- fails, as "root" doesn't exist
It's weird, because when I add chart.js using <script></script> that console.log(this) outputs the window object/scope, but when executed from browserify, it's undefined, that's why the chart.js fails.
I'm a total newb with browserify/node/gulp, but I tried different stuff such as:
Browserify-shim -> same error
Requiring the script in different ways, like trying to require it inside an object { }, trying to do a var whatever = new require('./vendors/chart') but failed miserably like a beheaded chicken trying to go to the bathroom.
I'm guessing that somehow I have to attach that script to an object or something so this would not be undefined when executed, but I'm failing to find the way.
I already solved it. The problem was a browserify transform called Babelify. I still don't know why Babel was doing that, but I didn't need it anyway so I just disabled it and that was it. Just posting it here in case it happens to someone else.

'Error: Unexpected request' during Karma Angular Unit Test

When running grunt karma, a test on one of the directive fails when it tries to fetch the template. I am using ng-html2js as a preprocessor. Here is some of my karma.conf.js
plugins: ['karma-chrome-launcher',
'karma-jasmine',
'ng-html2js',
'karma-ng-html2js-preprocessor'],
preprocessors: {
'app/scripts/directives/**/*.html': 'ng-html2js'
},
ngHtml2JsPreprocessor: {
moduleName: 'templates'
}
In my test, I have the following:
'use strict';
describe('Directive: myDirective', function () {
// load the directive's module
beforeEach(module('myApp'));
beforeEach(module('templates'));
var element,
scope;
beforeEach(inject(function ($rootScope) {
scope = $rootScope.$new();
}));
it('should not show search area initially', inject(function ($compile) {
element = angular.element('<navbar></navbar>');
element = $compile(element)(scope);
scope.$digest();
expect(element.find('.myClass').hasClass('myClass')).toBe(true);
}));
});
When I run the test, I get
Error: Unexpected request: GET /scripts/directives/myDirective/myDirective.html
It seems like the preprocessor is not properly injecting the javascript version of the template.
I have also tried using the path of the template in the beforeEach(module('')); but that causes an error that reads:
Error: [$injector:modulerr] Failed to instantiate module...
How can I fix this?
I had kind of the same problem. Be sure you have the exact file match. Open the Google chrome console and check the file path is exactly the same.
In the upper exemple, I had to add a "/" string in ngHtml2JsPreprocessor.stripPrefix and it worked.
So I guess with Yeoman, you should use
ngHtml2JsPreprocessor: {
moduleName: 'templates',
stripPrefix: 'app/' //add a slash
}
Since I was using the Yeoman tool to scaffold my project, I needed to add a stripPrefix to the ngHtml2JsPreprocessor option in my karma.conf.js file:
ngHtml2JsPreprocessor: {
moduleName: 'templates',
stripPrefix: 'app'
}

Categories