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_){
    varcontroller, 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……
If you want to explore my playground, follow this github repository: https://github.com/masudiiuc/angular-unit-test
