New to Jasmine, I am trying to instantiate my controller which has a list of dependencies (mainly the services I have written) and all the different ways I';ve tried haven't been right.
Here is my controller:
(function () {
'use strict';
angular.module('app.match')
.controller('MatchController', MatchController);
MatchController.$inject = ['APP_CONFIG', '$authUser', '$http', '$rootScope', '$state', '$stateParams', 'SearchService', 'ConfirmMatchService', 'MusicOpsService', 'ContentOpsService', 'MatchstickService', 'MatchService', 'Restangular'];
function MatchController(APP_CONFIG, $authUser, $http, $rootScope, $state, $stateParams, searchService, confirmMatchService, musicOpsService, contentOpsService, matchstickService, matchService, Restangular) {
var vm = this;
vm.greeting = '';
.
.
)();
Here is my test
(function(){
'use strict';
describe('app module', function() {
var MatchController;
//beforeEach(module('app.match'));
beforeEach(function($provide) {
module = angular.module('app.match');
$provide.service('SearchService', function(){
});
});
beforeEach(module('app.config'));
beforeEach(module('auth'));
beforeEach(inject(function($controller, APP_CONFIG, $authUser, $http, $rootScope, $state, $stateParams) {
MatchController = $controller('MatchController', {'APP_CONFIG':APP_CONFIG, '$authUser':$authUser, '$http':$http, '$rootScope':$rootScope, '$state':$state, '$stateParams':$stateParams, '$provide':$provide});
}));
describe("Match controller", function() {
it("should be created successfully", function() {
expect(MatchController).toBeDefined();
});
});
});
})();
Running test the above way gives me the following error:
TypeError: 'undefined' is not a function (evaluating '$provide.service('SearchService', function(){
})')
Try injecting the SearchService like this instead of using beforeEach.
describe('app module', function() {
var MatchController, SearchService;
beforeEach(module('app.match'));
beforeEach(module('app.config'));
beforeEach(module('auth'));
beforeEach(inject(function($controller, APP_CONFIG, $authUser, $http, $rootScope, $state, $stateParams, _SearchService_) {
SearchService = _SearchService_;
MatchController = $controller('MatchController', {
'APP_CONFIG':APP_CONFIG,
'$authUser':$authUser,
'$http':$http,
'$rootScope':$rootScope,
'$state':$state,
'$stateParams':$stateParams,
'$provide':$provide,
'SearchService': _SearchService_
});
}));
describe("Match controller", function() {
it("should be created successfully", function() {
expect(MatchController).toBeDefined();
});
});
});
})();
Similarly, you'll have to inject other services as well that your controller is relying on.
Related
I am trying to write test case for angularjs controller via karma jasmine
Getting below error
Error: [$controller:ctrlreg] The controller with the name 'ApproveRejectPackageController' is not registered.
This is my controller code and supporting test case
(function() {
angular.module('Citi.iv.FC')
.controller('ApproveRejectPackageController', ['$scope', '$filter', '$timeout','$uibModal','$sce', '$stateParams', function ($scope,$filter, $timeout, $uibModal, $sce, $stateParams) {});
describe('myserv', function () {
var service;
var data;
beforeAll(function () {
module('Citi.iv.FC')
});
beforeEach(inject(function($controller, $rootScope) {
scope = $rootScope;
secondController = $controller('ApproveRejectPackageController', {$scope: scope});
}));
it('ServiceTestSpec', function () {
expect(2 + 3).toBe(6);
});
});
Please suggest how to fix this.
I have included controller in karma-config file
I have a simple login controller:
'use strict';
angular.module('login', ['ngRoute'])
.config(['$routeProvider', function ($routeProvider) {
}])
.controller('LoginCtrl', ["$scope", "$route", "LoginService", function ($scope, $route, LoginService) {
var self = this;
this.showGuestLogin = true;
this.showUserLogin = false;
this.toggleUserLoginType = function () {
this.showGuestLogin = !this.showGuestLogin;
this.showUserLogin = !this.showUserLogin;
}
this.submitGuestLogin = function()
{
if(this.guestName === undefined || this.guestName.trim() == '')
{
self.loginError = "Name cannot be blank";
return;
}
LoginService.loginAsGuest(this.guestName.trim())
.then(function()
{
self.loginError = null;
$route.reload();
})
.catch(function(err)
{
self.loginError = 'An error occured. Please try again';
});
}
}]);
I am trying to test it with:
describe('LoginCtrl', function()
{
beforeEach(module('login'));
var ctrl;
beforeEach(inject(function($controller)
{
ctrl = $controller('LoginCtrl');
}));
it('should set error if guest name is undefined', function(done)
{
ctrl.guestName = undefined;
ctrl.submitGuestLogin();
expect(ctrl.loginError).toBeDefined();
});
});
But I am getting this error in console when test runs
Error: [$injector:unpr]
http://errors.angularjs.org/1.5.8/$injector/unpr?p0=%24scopeProvider%20%3C-%20%24scope%20%3C-%20LoginCtrl
I can see in the developer console in the karma driven browser that the controller and it's dependant files are all being loaded correctly.
I can't see what is wrong?
UPDATE
I have tried the suggestions of passing an empty object:
beforeEach(inject(function($controller, $scope, $route, LoginService)
{
ctrl = $controller('LoginCtrl', {
});
}));
and setting up the dependencies:
beforeEach(inject(function($controller, $scope, $route, LoginService)
{
ctrl = $controller('LoginCtrl', {
$scope: $scope,
$route: $route,
LoginService: LoginService
});
}));
Both of which give me this error:
Error: [$injector:unpr]
http://errors.angularjs.org/1.5.8/$injector/unpr?p0=%24scopeProvider%20%3C-%20%24scope
It's because you need to add in the scope in the injection like this:
beforeEach(inject(function($controller, $scope) {
ctrl = $controller('LoginCtrl', { $scope: $scope });
}));
Similarly, if your real controller has injections that you will be using for testing, you'll need to add them in. So for example (and this is only an example):
ctrl = $controller('LoginCtrl',
{
$scope: $scope,
SomeService: SomeService,
moment: moment,
dateFormat: dateFormat
});
Found an answer here which worked: Angular Unit Test Unknown provider: $scopeProvider
beforeEach(inject(function($controller, $rootScope, $route, LoginService)
{
scope = $rootScope.$new();
ctrl = $controller('LoginCtrl', {
$scope: scope
});
}));
In my case I didn't actually need $scope injected into my controller, so I removed it an the original code now works:
beforeEach(inject(function($controller, $rootScope, $route, LoginService)
{
ctrl = $controller('LoginCtrl');
}));
I need to read up on how mocks and injection works!
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
My service is:
myApp.service('userService', [
'$http', '$q', '$rootScope', '$state', '$cookies', '$base64', function($http, $q, $rootScope, $state, $cookies, $base64) {
var user;
user = {};
this.logout = function() {
user = {};
delete $cookies.userAccessKey;
return $state.transitionTo('login');
};
}
]);
I want to write a unit test to make sure that the $cookies.userAccessKey was deleted. How can I do this? While I'm at it, how can I ensure that user was set to empty?
To check if user is null, just add a public getter or checker :
myApp.service('userService', [
'$http', '$q', '$rootScope', '$state', '$cookies', '$base64', function($http, $q, $rootScope, $state, $cookies, $base64) {
var user;
this.user = {}; // or a method this.isLoggedIn() for more security
this.logout = function() {
this.user = {};
delete $cookies.userAccessKey;
return $state.transitionTo('login');
};
}
]);
Then, in your tests :
describe('logout', function(){
beforeEach(function(){
userService.login(); //relog before each test
});
it('should remove the userAccessKey from cookie', function() {
userService.logout();
inject(function($cookies) {
expect(cookies.userAccessKey).toBeUndefined();
});
});
it('should reset user object', function() {
userService.logout();
expect(userService.user).toEqual({});
});
});
});