'homecntrl' is not a function, got undefined in angularjs - javascript

I am trying to test my controller .I am able to make simple controller in angular js and able to test controller online .here is my code
http://plnkr.co/edit/xzvhXHPoUdulOM9clOkQ?p=preview
controller code
(function(){
'use strict';
angular.module('app.home').controller('homeCntrl',homeCntrl);
function homeCntrl(){
var home=this;
home.clickbtn=function(){
home.message='test';
alert(home.message)
}
}
})();
but when test in my pc it not run and getting this error
**Argument 'homecntrl' is not a function, got undefined
http://errors.angularjs.org/1.4.8/ng/areq?p0=homecntrl&p1=not%20a%20function%2C%20got%20undefined
at /Users/naveenkumar/Documents/ionic_work/SimpleDemo/bower_components/angular/angular.js:68:12**
here is my code of test
(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();
})
})
})()
I am able to test online but not able to test on pc
here is my code of pc
https://dl.dropbox.com/s/no901z41bza7osm/SimpleDemo.zip?dl=0
please download it and go to project directory and write npm install

You should update your controller name homeCntrl to homecntrl
(function(){
'use strict';
angular.module('app.home').controller('homecntrl',homeCntrl);
function homecntrl(){
var home=this;
home.clickbtn=function(){
home.message='test';
alert(home.message)
}
}
})();
It will be work.

Related

How to mock objects inside $scope or $window in AngularJs tests using Karma and Jasmine?

I am new to testing AngularJs controllers with Karma and Jasmine.
I'm trying to test this controller:
angular.module('app.dashboard.admin', [])
.controller('AdminCtrl', function (locale, $log, $scope, $window, $state) {
$scope.translation = $window.translation()[locale];
$scope.showAdminBoard = false;
$scope.initModel = {
disableProgress: false,
message: $scope.translation['admin_platform_init'],
error: ''
};
$scope.adminPrivileges = {};
$scope.onGetAdminPrivileges = function () {
return $scope.adinPrivileges;
}
Here's my test code:
'use strict';
describe('dashboard.admin module', function () {
beforeEach(function(){
module('app.dashboard.admin');
});
var auth, scope, ctrl, window;
beforeEach(inject(function ($controller, $rootScope, $window) {
auth = Auth;
scope = $rootScope.$new(); //get a childscope
window = {
translation: $window.translation
};
ctrl = $controller("AdminCtrl", {$scope: scope, $window: window});
}));
describe('Admin Controller', function () {
it('should inject controller', function () {
expect(ctrl).toBeDefined();
});
});
});
However, when I try to execute this test code I get this error:
TypeError: undefined is not an object (evaluating '$scope.translation['admin_platform_init']') (line 11)
views/dashboard.admin/admin.js:11:40
[native code]
instantiate#bower_components/angular/angular.js:4786:61
$controller#bower_components/angular/angular.js:10607:39
bower_components/angular-mocks/angular-mocks.js:2249:23
views/dashboard.admin/admin.spec.js:113:27
invoke#bower_components/angular/angular.js:4771:24
WorkFn#bower_components/angular-mocks/angular-mocks.js:3130:26
loaded#http://localhost:9876/context.js:151:17
inject#bower_components/angular-mocks/angular-mocks.js:3097:28
views/dashboard.admin/admin.spec.js:106:22
global code#views/dashboard.admin/admin.spec.js:3:9
Expected undefined to be defined.
views/dashboard.admin/admin.spec.js:118:37
loaded#http://localhost:9876/context.js:151:17
I have tried to mock the $window object and overriding angular's $window object, but I wasn't successful.
I have checked the dependencies in my karma.conf.js file and they're all there.
I have also checked these questions:
Karma-Jasmine: How to test $translate.use?
jasmine mock window object
but the proposed solutions didn't really help.
Thus, I'm trying to find a way to mock the $scope.translation['admin_platform_init'] object in order to be able to execute my tests.
Can someone please point me in the right direction?
Thank you.
try this instead of $window.translation
window = {
translation: function () {
return {
"admin_platform_init": "This is test message"
};
}
};
I managed to solve my problem by importing the 'app' module.
The test code after the fix looks like this:
'use strict';
describe('dashboard.admin module', function () {
beforeEach(function(){
module('app');
module('app.dashboard.admin');
});
var auth, scope, ctrl, window;
beforeEach(inject(function ($controller, $rootScope, $window) {
auth = Auth;
scope = $rootScope.$new(); //get a childscope
window = {
translation: $window.translation
};
ctrl = $controller("AdminCtrl", {$scope: scope, $window: window});
}));
describe('Admin Controller', function () {
it('should inject controller', function () {
expect(ctrl).toBeDefined();
});
});
});

karma test controller using toBeDefined failed

My test failed because it says my controller is not defined. So strange I think I did everything right.
describe('homeCtrl', function() {
var httpBackend, controller, scope;
beforeEach(module('App'));
beforeEach(inject(function($httpBackend, $controller) {
scope = {};
httpBackend = $httpBackend;
controller = $controller('homeCtrl', { $scope: scope });
}));
it('should exist', function() {
expect(controller).toBeDefined();
});
});
and I have my home.js which is the controller like this
var App = angular.module('App')
App.controller('homeCtrl', function($scope) {
})
The error is Expected undefined to be defined.
Your home.js should have dependencies injected in module, change it as,
var App = angular.module('App',[])
App.controller('homeCtrl', function($scope) {
})

writing jasmine unit test for angular factory

I am trying to test an angular factory using jasmine and mocha however I keep getting undefined errors.
here is my factory:
(function() {
'use strict';
angular.module('app').factory('appFactory', appFactory);
appFactory.$inject = ['$http','$q'];
function appFactory($http,$q) {
return {
get: get
};
function get(someData) {
//....
}
}
})();
and here is my unit test using jasmine and mocha:
'use strict';
describe('Factory: appFactory', function() {
var http, appFactory;
var $rootScope, $scope;
beforeEach(function() {
angular.module('app');
});
beforeEach(inject(function($injector) {
$rootScope = $injector.get('$rootScope');
$scope = $rootScope.$new();
}));
beforeEach(inject(function() {
var $injector = angular.injector(['ngMock', 'ng', 'app']);
appFactory = $injector.get('appFactory');
}));
it('should be defined', inject( function() {
alert(appFactory);
}));
});
so my alert looks something like:
Object{get: function get(someData) {...}
how do I go about testing the functionality of my factory if this is returning an object?

Writing Karma test for angularjs app

I am trying to figure out how to write some simple Karma tests, but am having some trouble with syntax and just understanding the framework. Here is a controller that I want to write a test for:
myApp.controller('menuController', ['$rootScope', '$parse', '$attrs', '$scope', 'Menu', 'Track', '$state',
function($rootScope, $parse, $attrs, $scope, Menu, Track, $state){
$scope.Menu = Menu;
$rootScope.$on("click",function() {
Menu.active = false;
});
$scope.click = function(button) {
Track.event(2, button + "_button_pressed", true);
};
}])
Here is a simple test I wrote for this controller, I am trying to test for the menu button's active status changing when it is clicked:
describe('Controller: menuController', function() {
//load the module with menuController
beforeEach(module('myApp'));
var MainCtrl,
scope;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
MainCtrl = $controller('menuController', {
$scope: scope
});
}));
//put test here
it ('should change $scope.Menu.active to true when button is clicked', function() {
expect(scope.Menu.active).toBeFalse();
scope.click();
expect(scope.Menu.active).toBeTrue();
})
});
After running Grunt test, the test fails and one of the errors it returns is:
TypeError: 'undefined' is not an object (evaluating 'scope.Menu')
I was hoping if anyone can tell me what I'm doing wrong or show me how to write a simple karma test for the controller shown above.
Thanks in advance!

$scopeProvider <- $scope/ Unknown provider

I testing my angular-application with jasmine(http://jasmine.github.io/2.0/) and getting next error:
Unknown provider: $scopeProvider <- $scope
I know, that it's incorrect to build dependency with scope in filters, services, factories, etc., but I use $scope in controller!
Why am i getting this error? controller looks like
testModule.controller('TestCont', ['$filter', '$scope', function($filter, $scope){
var doPrivateShit = function(){
console.log(10);
};
this.lol = function(){
doPrivateShit();
};
this.add = function(a, b){
return a+b;
};
this.upper = function(a){
return $filter('uppercase')(a);
}
$scope.a = this.add(1,2);
$scope.test = 10;
$scope.search = {
};
}]);
and my test's code:
'use strict';
describe('testModule module', function(){
beforeEach(function(){
module('testModule');
});
it('should uppercase correctly', inject(function($controller){
var testCont = $controller('TestCont');
expect(testCont.upper('lol')).toEqual('LOL');
expect(testCont.upper('jumpEr')).toEqual('JUMPER');
expect(testCont.upper('123azaza')).toEqual('123AZAZA');
expect(testCont.upper('111')).toEqual('111');
}));
});
You need to manually pass in a $scope to your controller:
describe('testModule module', function() {
beforeEach(module('testModule'));
describe('test controller', function() {
var scope, testCont;
beforeEach(inject(function($rootScope, $controller) {
scope = $rootScope.$new();
testCont = $controller('TestCont', {$scope: scope});
}));
it('should uppercase correctly', function() {
expect(testCont.upper('lol')).toEqual('LOL');
expect(testCont.upper('jumpEr')).toEqual('JUMPER');
...
});
});
});
Normally, a $scope will be available as an injectable param only when the controller is attached to the DOM.
You need to associate somehow the controller to the DOM (I'm mot familiar with jasmine at all).
I am following a video tutorial from egghead (link bellow) which suggest this approach:
describe("hello world", function () {
var appCtrl;
beforeEach(module("app"))
beforeEach(inject(function ($controller) {
appCtrl = $controller("AppCtrl");
}))
describe("AppCtrl", function () {
it("should have a message of hello", function () {
expect(appCtrl.message).toBe("Hello")
})
})
})
Controller:
var app = angular.module("app", []);
app.controller("AppCtrl", function () {
this.message = "Hello";
});
I am posting it because in the answer selected we are creating a new scope. This means we cannot test the controller's scope vars, no?
link to video tutorial (1min) :
https://egghead.io/lessons/angularjs-testing-a-controller

Categories