In my last blog post, I talked about “Test angular service using Karma and Jasmine”. Today I am going to talk about “Test angular controller using Karma and Jasmine”.

Testing Controller

Lets create a controller test file users.js and do as follows:

describe("UserController", function () { });

Let’s mock our angular module component.users using angular.mock in the following way:

describe("UserController", function () { beforeEach(angular.mock.module('component.users')); });

To identify the controller users.js we need to add the dependency (inject) to our angular.mock.module in the following way:

beforeEach(inject(function (_ controller_){ controller = _ controller_; UsersController = controller('UsersController', {}); }));

Here we two undefined variable $controller and UsersController. Lets defined them:

beforeEach(inject(function (_ controller_){ var controller, UsersController; controller = _ controller_; UsersController = $controller('UsersController', {}); }));

Now lets start our first test case to check whether the controller is defined or not. To do so, follow this:

describe('UsersController', function () { var controller, UsersController, userService; beforeEach(angular.mock.module('component.users')); beforeEach(inject(function (_ controller){ controller = _ controller_; UsersController = $controller('UsersController', {}); })); it (' should be defined ', function () { expect(UsersController).toBeDefined(); }); });

Now if we run the following command:

# karma start

it will display error with controller file name. To resolve this error lets create our controller file users.js :

(function (){ 'use strict'; angular.module('component.users', []).controller('UsersController', usersController); usersController.$inject = [] function usersController() { var vm = this; } }());

This time, you will see test case passed:

Chrome 56.0.2924 (Mac OS X 10.12.0): Executed 1 of 1 SUCCESS (0.062 secs / 0.083 secs) TOTAL: 1 SUCCESS

Testing Controller with Service Dependency

Let’s add the dependency user-service.js (that we created in my last blog post) to the controller and write the test for that.

First modify users.spec.js file as follows:

describe('UsersController', function () { var controller, UsersController, userService; // add this beforeEach(angular.mock.module('component.users')); beforeEach(angular.mock.module('component.users.service')); //add this beforeEach(inject(function (_ controller_, _UserService_) { // add this controller = _ controller_; userService = _UserService_; // add this UsersController = $controller('UsersController', {'UserService': userService}); // add this })); it (' should be defined ', function () { expect(UsersController).toBeDefined(); }); });

Now if you run # karma start you will see an error, like that

Error: [$injector:unpr] Unknown provider: UserServiceProvider <- UserService <- UsersController

To fix this error, modify users.js controller by adding the service dependency:

(function (){ 'use strict'; angular.module('component.users', []).controller('UsersController', usersController); usersController.$inject = ['UserServic1e'] function usersController(UserService) { var vm = this; } }());

This time you not see any more error.

Now lets define a method userService.all() in service and try to access it in controller users.js .

Update the controller test file users.spec.js file:

describe('UsersController', function () { var controller, UsersController, userService; beforeEach(angular.mock.module('component.users')); beforeEach(angular.mock.module('component.users.service')); beforeEach(inject(function (_ controller_, _UserService_){ controller = _ controller_; userService = _UserService_; UsersController = $controller('UsersController', {'UserService': userService}); })); it (' should be defined ', function () { expect(UsersController).toBeDefined(); }); // add this Test Case it('should Initlialized with a call to UserService.all()', function (){ expect(userService.all).toHaveBeenCalled(); }); });

This time if you run # karma start , you will see an error like that:

To resolve this error we are going to use spyOn method of Jasmine. Click here to know more about spyOn,

describe('UsersController', function () { var controller, UsersController, userService; beforeEach(angular.mock.module('component.users')); beforeEach(angular.mock.module('component.users.service')); beforeEach(inject(function (_ controller_, _UserService_){ controller = _ controller_; userService = _UserService_; spyOn(userService, 'all').and.callFake(function (){ return [{ id: '1', name: 'Masud', role: 'Developer', location: 'CA', twitter: 'masudiiuc' }]; }); UsersController = $controller('UsersController', {'UserService': userService}); })); it (' should be defined ', function () { expect(UsersController).toBeDefined(); }); it('should Initlialized with a call to UserService.all()', function (){ expect(userService.all).toHaveBeenCalled(); expect(userService.all()).toEqual(userList); }); });

Now if you run # karma start you will see the following error:



Let’s define the method in our user-service.js file:

(function (){ 'use strict'; angular.module('component.users.service', []).service('UserService', userService); function userService() { this.all = all; function all(){ return [{ id: '1', name: 'Masud', role: 'Developer', location: 'CA', twitter: 'masudiiuc' }]; } }; }());

Now if you run # karma start you will not see any error. Now add another Test Case like that:



it('should Initlialized with a call to UserService.all()', function (){ expect(userService.all).toHaveBeenCalled(); expect(userService.all()).toEqual( [{ id: '1', name: 'Masud', role: 'Developer', location: 'CA', twitter: 'masudiiuc' }] ); // add this });

That’s it. Now enjoy Testing your angular application.

Help:

– Testing AngularJS with Jasmine and Karma

– Jasmine SpyOn

Continue……