This blog will build on that one and show how to unit test a controller.
First step
In my testLoader.js header file I add my areaController the same way I added areaService.
Controller
The controller has a dependency on the areaService that we unit tested in the previous article. It also handles a click event which will set a $rootScope variable. The actual page transition happens in the view via Ionic's state routing. See below for the actual view code.
angular.module('locationApp').controller('AreaCtrl', function($rootScope, $scope, AreaService) { $scope.areas = AreaService.all(); $scope.rowClick = function(areaName) { $rootScope.areaName = areaName; }; } );
Unit Test
I want my unit test to verify that the $scope object has the right areas and that when the click event happens, the $rootScope variable is set correctly.
We are going to mock the areaService object with fake data and we'll also tell the controller injection service to use our mock.
By calling the inject function in beforeEach, I'm able to make class-level variables to check the $scope and $rootScope of the controller. Note that most tutorials online choose to name these class-level variables with a leading $, but I chose not to do them that way.
require('../../testLoader'); describe('area controller', function() { var areaService, controller, rootScope, scope; beforeEach(function () { areaService = { all: function() { return [{id:1,name:'Area1'},{id:2,name:'Area2'}]; } }; angular.mock.module('locationApp', function($provide) { $provide.value('AreaService', areaService); }); inject(function($rootScope, $controller) { scope = $rootScope.$new(); rootScope = $rootScope; controller = $controller('AreaCtrl', { $scope: scope }); }); }); it('returns the correct number of areas in $scope.areas', function() { var areas = scope.areas; expect(areas.length).toBe(2); expect(areas[0].name).toBe('Area1'); }); it('sets the $rootScope.areaName when a rowClick event is raised', function() { expect(rootScope.areaName).toBeFalsy(); scope.rowClick('Test Area'); expect(rootScope.areaName).toBeTruthy(); }); });
View
FYI, I'm using the BindOnce library, hence the bo-text directive.
<ion-view title="Areas"> <ion-content class="has-header"> <ion-list> <ion-item bindonce="" href="#/tab/facilities/{{area.id}}" ng-click="rowClick(area.name)" ng-repeat="area in areas | orderBy:'name'" type="item-text-wrap"> <span bo-text="area.name"></span> </ion-item> </ion-list> </ion-content> </ion-view>
Great Article
ReplyDeleteFinal Year Projects for CSE in Angular
Angular Training in Chennai
Project Centers in Chennai
JavaScript Training in Chennai