I tried test a function enside a controller in angularjs, but always fail.
this is for angularjs project
//controller---
'use strict';
angular.module('My_module').controller('my_controller', function (
$scope, $route, $timeout, $routeParams) {
function first_function(data) {
return and_array;
}
function second_function() {
return and_obj;
}
}
//-----Spec----
'use strict';
describe('My tests specs', function () {
var route;
var scope;
var my_controller;
beforeEach(function () {
controller();
});
describe('first test', function(){
it('test functions', fucntion(){
expect(my_controller_Mock.first_function).toHaveBeenCalled();
});
});
function controller() {inject(function ($rootScope, $controller,
$route) {
route = $route;
scope = $rootScope.$new();
//--i tried these
my_controller_Mock = jasmine.createSpyObj('my_controller',
['first_function'])
$controller('my_controller', {
$scope: scope,
$route: route,
my_controller: my_controller_Mock
});
}
jasmine Error: Expected spy my_controller.first_function to have been called
In your example, you're never calling first_function, so jasmine is correct that's it's not being called.
Related
I am new to AngularJS and working on adding unit tests in Karma and Jasmine. I have a following controller code whose method I am trying to test. I am getting the error saying that Expected undefined to be defined. I am not sure why SpyOn is not able to recognize the method. Any help is appreciated. Thanks in advance.
newclaim.js
(function () {
'use strict';
var controllerId = 'createnewclaim';
angular.module('app').controller(controllerId, ['$location', '$routeParams', 'sessionKeys', 'securelogins',
'localStorageService', 'common', 'config', 'datacontext', createnewclaim]);
function createnewclaim($location, $routeParams, sessionKeys, securelogins, localStorageService, common, config, datacontext) {
//some code here
My test file code
describe('testing AngularJS Test Suite', function () {
beforeEach(module('app'));
describe('Testing AngularJS NewClaim Controller', function () {
var scope = {};
var ctrl;
var controllerId = 'createnewclaim';
beforeEach(inject(function ($controller, $rootScope, localStorageService, common, datacontext, sessionKeys, securelogins) {
scope = $rootScope.$new();
ctrl = function () {
$controller(controllerId, {
$scope: scope,
localStorageService: localStorageService,
common: common,
datacontext: datacontext,
sessionKeys: sessionKeys,
securelogins: securelogins
});
};
}));
it('controller defined', inject(function () {
expect(ctrl).toBeTruthy();
}));
it('controller function defined', inject( function () {
ctrl();
expect(ctrl.createnewclaim).toBeDefined();
}));
});
});
})();
Sorry. Ignore the return. You need to be using the scope as your test, not the ctrl.
describe('testing AngularJS Test Suite', function () {
beforeEach(module('app'));
describe('Testing AngularJS NewClaim Controller', function () {
var scope = {};
var ctrl;
var controllerId = 'createnewclaim';
beforeEach(inject(function ($controller, $rootScope, localStorageService, common, datacontext, sessionKeys, securelogins) {
scope = $rootScope.$new();
ctrl = function () {
return $controller(controllerId, {
$scope: scope,
localStorageService: localStorageService,
common: common,
datacontext: datacontext,
sessionKeys: sessionKeys,
securelogins: securelogins
});
};
}));
it('controller defined', inject(function () {
ctrl();
expect(scope).toBeTruthy();
}));
it('controller function defined', inject( function () {
ctrl();
expect(scope.createnewclaim).toBeDefined();
}));
});
});
})();
I'm getting the below error while doing karma/jasmine unit testing for both the test cases.I tried by modifying the controller by adding angular.controller in the spec file even then it is not working.Is there any way to fix?
TypeError: undefined is not a constructor (evaluating 'angular.controller('myView')')
myView.spec.js
// myView.spec.js
(function(){
describe('controller: myView', function(){
var module,myView,$q, $rootScope, $scope, uiGridConstants, overviewService, commonService, $timeout;
beforeEach(function() {
module = angular.module('app.myView');
controller= angular.controller('myView')
});
beforeEach(inject(function ($controller, _$q_, _$rootScope_, _$timeout_) {
$q= _$q_;
$rootScope = _$rootScope_;
$timeout= _$timeout_;
myView= $controller('myView', {
$q : _$q_,
$rootScope : _$rootScope_,
$timeout: _$timeout_
});
}));
describe("myViewto be defined", function() {
it("should be created successfully", function () {
expect(controller).toBeDefined();
});
it("overview should be defined", function () {
expect(myView()).toBeDefined();
});
});
});
})();
and myView.js
(function() {
'use strict';
angular
.module('app.myView')
.controller('myView', myView);
function myView($q, $rootScope, $scope, uiGridConstants, myViewService, commonService, $timeout) {
var vm = this;
vm.callFeedback = function () { };
})();
Sharing following code
// myView.spec.js
(function(){
describe('myView', function(){
var $controller, myView;
//we use angular-mocks to specify which modules we'll need within this
//test file.
beforeEach(angular.mock.module('app.myView'));
// Inject the $controller service to create instances of the controller
//(myView) we want to test
beforeEach(inject(function(_$controller_) {
$controller = _$controller_;
myView = $controller('myView', {});
}));
// Verify our controller exists
it('should be defined', function() {
expect(myView).toBeDefined();
});
});
})();
We set _$controller_to the $controller variable we created and then create an instance of our controller by calling $controller('myView', {}). The first argument is the name of the controller we want to test and the second argument is an object of the dependencies for our controller.
You should pass the injected parameters to your controller as shown:
(function() {
'use strict';
angular
.module('app.myView')
.controller($q,$rootScope,$scope,uiGridConstants,'myView', myView);
function myView($q, $rootScope, $scope, uiGridConstants, myViewService, commonService, $timeout) {
var vm = this;
vm.callFeedback = function () { };
})();
Also make sure that your module has all the necesary dependences in the angular.module('app.myView',['uiGridConstants', ...'etc']);
I am trying to test something pretty simple: a controller that calls a service that performs a http request.
Controller:
define(['module'], function (module) {
'use strict';
var MyController = function ($scope, MyService) {
$scope.testScope = 'karma is working!';
MyService.getData().then(function (data) {
$scope.result = data.hour
});
};
module.exports = ['$scope', 'MyService', MyController ];
});
Test:
define(['require', 'angular-mocks'], function (require) {
'use strict';
var angular = require('angular');
describe("<- MyController Spec ->", function () {
var controller, scope, myService, serviceResponse;
serviceResponse= {
id: 12345,
hour: '12'
};
beforeEach(angular.mock.module('myApp'));
beforeEach(inject(function (_$controller_, _$rootScope_, _MyService_, $q) {
scope = _$rootScope_.$new();
var deferred = $q.defer();
deferred.resolve(serviceResponse);
myService = _MyService_;
spyOn(myService, 'getData').and.returnValue(deferred.promise);
controller = _$controller_('MyController', {$scope: scope});
scope.$apply();
}));
it('should verify that the controller exists ', function() {
expect(controller).toBeDefined();
});
it('should have testScope scope equaling *karma is working*', function() {
expect(scope.testScope ).toEqual('karma is working!');
});
});
});
With the above, i get the error:
TypeError: 'undefined' is not an object (evaluating 'spyOn(myService, 'getData').and.returnValue')
Solved the question - was using Jasmine 1x.. Upgraded to 2.0 and works as expected
I make one controller in Angularjs and try to test that controller using Jasmine. I got this error Cannot read property 'message' of undefined why ?
Here is my code.
controller
(function(){
'use strict';
angular.module('app.home').controller('homeCntrl',homeCntrl);
function homeCntrl(){
var home=this;
home.clickbtn=function(){
home.message='test';
alert(home.message)
}
}
})();
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 ?durning testing I got this error .. ? can we do testing of this controller ?Every thing is fine on angular js code problem is on test code..only check appspec.js
Just an hint
app
(function() {
'use strict';
function HomeController() {
var home = this;
home.title = 'Home';
}
angular.module('home.controllers', [])
.controller('HomeController', HomeController);
})();
test
'use strict';
describe('home controller', function() {
var $controller;
var scope;
beforeEach(module('home.controllers'));
beforeEach(inject(function(_$controller_, $rootScope) {
$controller = _$controller_;
scope = $rootScope.$new();
$controller('HomeController as home', {$scope: scope});
}));
it('should have text = "Home"', function() {
expect(scope.home.title).toEqual('Home');
});
});
in your case the test should be like
scope.home.clickbtn();
expect(scope.home.message).toEqual('test');
Take a look at http://www.bradoncode.com/tutorials/angularjs-unit-testing/ to master unit test in angular
I have this simple controller, UserService is a service which return JSON
"use strict";
angular.module("controllers").controller('profileCtrl', ["$scope", "UserService",
function ($scope, UserService) {
$scope.current_user = UserService.details(0);
}
]);
I can not make the test. However this is my try
'use strict';
describe('profileCtrl', function () {
var scope, ctrl;
beforeEach(angular.mock.module('controllers'), function($provide){
$provide.value("UserService", {
details: function(num) { return "sdfsdf"; }
});
});
it('should have a LoginCtrl controller', function() {
expect(controllers.profileCtrl).toBeDefined();
});
beforeEach(angular.mock.inject(function($rootScope, $controller){
scope = $rootScope.$new();
$controller('profileCtrl', {$scope: scope});
}));
it('should fetch list of users', function(){
expect(controllers.scope.current_user.length).toBe(6);
expect(controllers.scope.current_user).toBe('sdfsdf');
});
});
The usage of $controller is correct, that's the way to instantiate a controller for a unit test. You can mock the UserService instance it gets directly in the $controller invocation.
You should be using its return value - this is the instance of your controller you're going to test.
You're trying to read stuff from controllers but its not defined anywhere in the test, I guess you're referring to the module.
This is how I would go about it + fiddle
//--- CODE --------------------------
angular.module('controllers', []).controller('profileCtrl', ["$scope", "UserService",
function ($scope, UserService) {
$scope.current_user = UserService.details(0);
}]);
// --- SPECS -------------------------
describe('profileCtrl', function () {
var scope, ctrl, userServiceMock;
beforeEach(function () {
userServiceMock = jasmine.createSpyObj('UserService', ['details']);
userServiceMock.details.andReturn('sdfsdf');
angular.mock.module('controllers');
angular.mock.inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
ctrl = $controller('profileCtrl', {
$scope: scope,
UserService: userServiceMock
});
});
});
it('should have a LoginCtrl controller', function () {
expect(ctrl).toBeDefined();
});
it('should fetch list of users', function () {
expect(scope.current_user).toBe('sdfsdf');
});
});
You're welcome to change the fiddle online to see how it affects testing results.