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
Notable usefulness in this Love Language Test made it easier to identify emotional preferences, providing clear explanations and relatable examples that enhance understanding and improve communication with partners and loved ones.
ReplyDeleteFocused learning is encouraged through this Excel Practice Sheet providing structured exercises engaging challenges and practical scenarios that enhance skills boost productivity and support mastery of spreadsheet tools
ReplyDeleteMeaningful functionality delivered by this Url Opener platform, improving user productivity significantly. The interface is straightforward, and the system runs efficiently, allowing users to manage multiple links without delays or confusion during their browsing activities.
ReplyDelete