Jasmine Unit Testing Angularjs - angularjs

I'm new to Unit Testing. I have followed the tutorials and I have everything
configured on node.js via npm. I have done some describe and it just to get the feel for ho things are set up and my spec runner is fine. The problem I'm trying to get test on controllers figured out but I run in a snag and been trying to figure things out for a while but I continue to get the same error so I thought I would reach out.
I'm trying to do a simple test on a LoginController but I continue to get the same error. I can't point out what I'm doing wrong. Trying to get over this hurdle.
TypeError: angular.mock.module is not a function:
spec runner index html file.
<!doctype html>
<html>
<head>
<title>Jasmine Spec Runner</title>
<link rel="stylesheet" href="../bower_components/jasmine-core/lib/jasmine-core/jasmine.css">
</head>
<body>
<script src="../My Documents/My Website/AngularLogin-
Registration/js/angular-1.6.0.js"></script>
<script src="../My Documents/My Website/AngularLogin-Registration/js/angular-route-1.6.0.min.js"></script>
<script src="../bower_components/jasmine-core/lib/jasmine-core/jasmine.js"></script>
<script src="../bower_components/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
<script src="../bower_components/jasmine-core/lib/jasmine-core/boot.js"></script>
<!-- include source files here... -->
<!--<script src="//code.jquery.com/jquery-3.1.1.min.js"></script>-->
<!--<script src="//code.angularjs.org/1.6.0/angular-cookies.min.js"></script>-->
<script src="../My Documents/My Website/AngularLogin-Registration/js/angular-mock.js"></script>
<script src="../My Documents/My Website/AngularLogin-Registration/js/app.js"></script>
<script src="../My Documents/My Website/AngularLogin-Registration/login/login.controller.js"></script>
<!-- include spec files here... -->
<script src="spec/test.js"></script>
Here is my test file.
describe('LoginController test', function () {
beforeEach(angular.mock.module('app'));
beforeEach(angular.mock.inject(function(_$controller_){
$controller = _$controller_;
}));
describe('$scope.grade', function() {
it('sets the strength to "strong" if the password length is >8 chars',
function() {
var $scope = {};
var controller = $controller('LoginController', { $scope: $scope });
$scope.password = 'longerthaneightchars';
$scope.grade();
expect($scope.strength).toEqual('strong');
});
});
});
Thanking You In Advance
PDH

Load angular-mocks library in your spec runner html , make sure to load it after angular.js.
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular-mocks.js"></script>
You can also use bower to download the js file instead of the CDN.

Related

Angularjs/Karma: Uncaught ReferenceError: inject is not defined

I got this service
angular.module('common.utils', [])
.service('Timer', function () {
function Timer() {
var start = new Date();
return function () {
return (new Date()).getTime() - start.getTime();
};
}
return Timer;
});
And i'm trying to write a simple test for it:
describe('common.utils', function() {
beforeEach(function () {
module('common.utils');
});
it('has a timer service', inject(function(Timer) {
expect(Timer).not.toBeNull();
}));
});
And I keep getting ReferenceError: inject is not defined.
I included angular.js, angular-mocks.js and all the app files (module is working... ). I don't understand what the problem is...
I had the same problem.
It turns out the issue was in the loading order of the files. You have to load jasmine before you load angular-mocks.
The following loading order will be throwing the error as mentioned in the question:
<script src="/bower_components/angular/angular.js"></script>
<script src="/bower_components/angular-mocks/angular-mocks.js"></script>
<script src="/bower_components/jasmine/lib/jasmine-core/jasmine.js"></script>
<script src="/bower_components/jasmine/lib/jasmine-core/jasmine-html.js"></script>
<script src="/bower_components/jasmine/lib/jasmine-core/boot.js"></script>
<!-- include spec files here... -->
<script src="/spec/test.js"></script>
ReferenceError: inject is not defined
In several jasmine examples there is an additional comment included in the code:
<!-- include source files here... -->
The comment helps us to remind to load things in the right order.
<script src="/bower_components/jasmine/lib/jasmine-core/jasmine.js"></script>
<script src="/bower_components/jasmine/lib/jasmine-core/jasmine-html.js"></script>
<script src="/bower_components/jasmine/lib/jasmine-core/boot.js"></script>
<!-- include source files here... -->
<script src="/bower_components/angular/angular.js"></script>
<script src="/bower_components/angular-mocks/angular-mocks.js"></script>
<!-- include spec files here... -->
<script src="/spec/test.js"></script>

Angular Module 'cordovaHTTP' is not available

I am running Ionic and trying to use cordovaHTTP for SSL pinning. I followed the instructions on the the github but I get the error that the module isn't there.
My index.html
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="cordova.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
My app.js:
angular.module('starter', ['ionic', 'starter.controllers', 'starter.services', 'cordovaHTTP'])
In services.js:
angular.module('starter.services', [])
.service('MyService', function(cordovaHTTP) {
cordovaHTTP.enableSSLPinning(true, function() {
console.log('successful ssl pin');
cordovaHTTP.useBasicAuth("user", "pass", function() {
console.log('successful basic auth!');
cordovaHTTP.get(url, function(response) {
console.log(response.status);
}, function(response) {
console.error(response.error);
});
}, function() {
console.log('error basic auth');
});
}, function(){
console.log('error ssl pin');
});
});
This results in the error:
Uncaught Error: [$injector:modulerr] Failed to instantiate module starter due to:
Error: [$injector:modulerr] Failed to instantiate module cordovaHTTP due to:
Error: [$injector:nomod] Module 'cordovaHTTP' 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.
I have tried messing with this countless times but no dice. Any help is appreciated.
Actually I think you're initializing your module multiple times. In angular factories / services are singleton. Your code look like something this
angular.module('starter', ['ionic', 'MyService', 'cordovaHTTP']) //setters for a module
Please make sure you're injecting right service or factory name. You should change your service declaration way too, like below
angular.module('starter') //Don't use [] it is only getter of above initialized module
.service('MyService', function(cordovaHTTP){
//Code
});
Also please don't forget to load app.js at last. Hope it may help you.
I found the solution from github issues.
Make sure that you load the angular js files after cordova js files in index.html.
Here's my index.html:
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="lib/jquery/jquery-3.2.1.min.js"></script>
<script src="lib/ngCordova/dist/ng-cordova.min.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/routes.js"></script>
<script src="js/directives.js"></script>
<script src="js/services.js"></script>
Is angular defined?
cordova-HTTP will only instantiate the cordovaHTTP module if angular is defined otherwise it will fall back to window.cordovaHTTP.
You could use this this:
document.addEventListener("deviceready", function () {
console.log(window.cordovaHTTP);
console.log(window.CordovaHttpPlugin); // For some version it's instantiated in this name if angular is not defined.
}, false);
Manually bootstrap your AngularJS app instead of using the ng-app attribute.
Code:
<script>
angular.element(document).ready(function() {
document.addEventListener("deviceready", function () {
console.log(window.cordovaHTTP);
console.log(window.CordovaHttpPlugin); // For some version it's instantiated in this name if angular is not defined.
angular.bootstrap(document, ['MyAppName']);
}, false);
});
</script>
When using it in your controller or service, do not need to add the $.
Just use it like this:
angular.module('MyAppName.services', [])
.service('MyService', ['cordovaHTTP', function(cordovaHTTP){
// Your codes are here.
}]);

Jasmine 2.3 and Ext JS 5.0.1

I am trying to test an Ext JS 5.0.1 application with Jasmine 2.3.4. I keep getting the error "Uncaught ReferenceError: describe is not defined". It is as though it is not seeing describe, it, and other global functions. If I switch out the Jasmine files to 1.3, then it does see these global functions. I want to use the newest version of Jasmine and furthermore, I am not sure 1.3 plays well with Ext JS 5. Has anyone else run into this issue? Code snippets below:
specrunner.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test Application</title>
<!--Jasmine Files -->
<link rel="stylesheet" type="text/css" href="/app_name/app/js/jasmine/jasmine.css">
<script type="text/javascript" src="/app_name/app/js/jasmine/jasmine.js"></script>
<script type="text/javascript" src="/app_name/app/js/jasmine/jasmine-html.js"></script>
<!-- ExtJS Files -->
<script type="text/javascript" src="//cdn-tst.corporate.com/LNF/4/4.0.1/extjs/ext-all-debug.js"></script>
<script type="text/javascript" src="//cdn-tst.corporate.com/LNF/4/4.0.1/extjs/packages/ext-theme-classic/build/ext-theme-classic.js"></script>
<!-- Jasmine Test Case File -->
<script type="text/javascript" src="/app_name/app/js/spec/AppSpec.js"></script>
<!-- app Test Case File -->
<script type="text/javascript" src="/app_name/app/js/test/app.js"></script>
</head>
<body>
</body>
</html>
app.js (for testing)
Ext.Loader.setConfig ({enabled: true});
// Loading different components like controller, model, view..
Ext.application ({
models: [ 'Trip' ],
stores: [ 'Trips' ],
// views: [ 'simpleTrip' ], Views are throwing an error
autoCreateViewport: false,
name: 'carrier360',
// using the Launch method of Application object to execute the Jasmine Test Cases
launch: function () {
debugger;
var jasmineEnv = jasmine.getEnv ();
jasmineEnv.updateInterval = 1000;
var htmlReporter = new jasmine.HtmlReporter ();
jasmineEnv.addReporter (htmlReporter);
jasmineEnv.execute ();
}
});
AppSpec.js
describe ("ExtJS App Test Suite", function () {
debugger;
beforeEach (function () {
// Initializing the mainPanel
debugger;
tripsStore = Ext.StoreManager.lookup ('Trips');
simpleTrip = Ext.create ('app.view.simpleTrip');
controller = Ext.create ('view.controller.tripController');
});
/* Test if View is created Successfully.*/
it ('View is loaded', function () {
debugger;
expect (simpleTrip != null).toBeTruthy ();
});
/* Test if store is loaded successfully.*/
it ('Store shouldn’t be null', function () {
debugger;
expect (tripsStore != null).toBeTruthy();
});
/* Test controller is initialized successfully.*/
it ('Controller shouldn’t be null', function () {
debugger;
expect (controller != null).toBeTruthy();
});
});
Any suggestions on why describe and other functions are not visible would be appreciated!
Descibre, it, ... are no longuer defined in jasmine.js but instead in the boot.js included with jasmine library.

including external js file into angular

I have a java script file that contains a config object for decoding a lot of business jargon for ease of use in my application.
How can I get that to be available to my angular app? I currently have it included in my html file above all the application files.
here is my config.js:
var config = {
"metadata":[
"8235205241531AF399B113140005492E":{
"name":"verison_number"
}
]
}
here is includes:
<script src="libs/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="libs/angular/angular.min.js"></script>
<script src="libs/angular-resources/angular-resource.min.js"></script>
<script src="libs/angular-route/angular-route.min.js"></script>
<script src="js/config.js"></script>
<script src="js/viewer.js"></script>
<script src="js/controller.js"></script>
<script src="js/services.js"></script>
<script src="js/routes.js"></script>
<script src="js/app.js"></script>
now here is my controller just trying to do a console.log on it:
var MainCtrl = angular.module('MainCtrl', []);
MainCtrl.controller('loader',['$scope','$rootScope','$http','startApp', function($scope,$rootScope,$http,startApp) {
console.log(config);
console.log('loading course...');
console.log(startApp);
}]);
Your JSON is incorrect.
Here is the correct way for declaring config:
var config = {
"metadata":[
{"8235205241531AF399B113140005492E":"verison_number"}
]}
Working Plunkr
Maybe using the value recipe. For example:
var app = angular.module('MainCtrl');
// later
app.value('myconfigs',config); // set your "object"
// somewhere in your controller code
MainCtrl.controller('loader',['$scope','$rootScope','$http','startApp','myconfigs', function($scope,$rootScope,$http,startApp, myconfig) {
console.log(myconfig.metadata);
console.log('loading course...');
console.log(startApp);
}]);

why do I get 'inject' undefined error when using Jasmine with Angular?

I am Jasmine/AngularJS unit testing newbie. I created a simple angular app to add two numbers so that I can learn how to write unit tests for Angular App. The Angular Doc on unit test is incomplete.Based on the blogs and stack overflow answers, I build my first test and I am running into 'injector' undefined error. I am using Jasmine framework for the unit testing.
HTML
<body>
<div ng-controller="additionCtrl">
First Number: <input ng-model="NumberOne"/><br/>
Second Number: <input ng-model="NumberTwo"/>
<button ng-click="add(NumberOne, NumberTwo)">Add</button><br/>
Result: {{Result}}
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<script src="Scripts/additionCtrl.js"></script>
</body>
Controller:
function additionCtrl($scope) {
$scope.NumberOne = 0;
$scope.NumberTwo = 0;
$scope.Result = 0;
$scope.add = function (a, b) {
};
}
Jasmine spec file.
describe("Addition", function () {
var $scope, ctrl;
beforeEach(inject(function ($rootScope, $controller) {
this.scope = $rootScope.$new();
ctrl = $controller('additionCtrl', {
$scope: this.scope
});
}));
it("should add two integer numbers.", inject(function ($controller) {
expect(ctrl.add(2, 3)).toEqual(5);
}));
});
Specrunner.html
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<script type="text/javascript" src="lib/angular-mocks.js"></script>
<script type="text/javascript" src="lib/jasmine-1.3.1/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-1.3.1/jasmine-html.js"></script>
<!-- include source files here... -->
<script type="text/javascript" src="../App/Scripts/additionCtrl.js"></script>
<!-- include spec files here... -->
<script type="text/javascript" src="spec/addition.spec.js"></script>
This is a failing test and once the test fails with the expected result then I can modify the code to make it pass, but I am facing the problem with somehow angular mock is not getting injector.
I saw an example where I can newup a controller instead of using injector, but I would like to try to learn on using injector so that I am set up more complex tests. I might be missing something simple here. Please direct me to any write up I might have missed.
Thanks
For future reference here's a Plunker with a full unit test setup (for the answer to your question I was about to post)
http://plnkr.co/edit/KZGKM6
Useful to have this setup available for sharing test scenarios.
Found the problem, the url I was using to access angular-mock was wrong. I changed it to "http://code.angularjs.org/1.0.6/angular-mocks.js" and also changed the order of the script tags to
<script type="text/javascript" src="lib/jasmine-1.3.1/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-1.3.1/jasmine-html.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<script type="text/javascript" src="http://code.angularjs.org/1.0.6/angular-mocks.js"></script>
now it is failing on the method as it is supposed to be.

Resources