I am just starting with angular and I wanted to write some simple unit tests for my controllers, here is what I got.
app.js:
'use strict';
// Declare app level module which depends on filters, and services
angular.module('Prototype', ['setsAndCollectionsService']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/dashboard', {templateUrl: 'partials/dashboard.html', controller: 'DashboardController'});
$routeProvider.when('/setsAndCollections', {templateUrl: 'partials/setsAndCollections.html', controller: SetsAndCollectionsController});
$routeProvider.when('/repetition', {templateUrl: 'partials/repetition.html', controller: RepetitionController});
$routeProvider.otherwise({redirectTo: '/dashboard'});
}]);
and controllers.js
'use strict';
/* Controllers */
var myApp = angular.module('Prototype');
myApp.controller('DashboardController', ['$scope', function (scope) {
scope.repeats = 6;
}]);
/*function DashboardController($scope) {
$scope.repeats = 5;
};*/
function SetsAndCollectionsController($scope, $location, collectionsService, repetitionService) {
$scope.id = 3;
$scope.collections = collectionsService.getCollections();
$scope.selectedCollection;
$scope.repetitionService = repetitionService;
$scope.switchCollection = function (collection) {
$scope.selectedCollection = collection;
};
$scope.addCollection = function () {
$scope.collections.push({
name: "collection" + $scope.id,
sets: []
});
++($scope.id);
};
$scope.addSet = function () {
$scope.selectedCollection.sets.push({
name: "set" + $scope.id,
questions: []
});
++($scope.id);
};
$scope.modifyRepetition = function (set) {
if (set.isSelected) {
$scope.repetitionService.removeSet(set);
} else {
$scope.repetitionService.addSet(set);
}
set.isSelected = !set.isSelected;
};
$scope.selectAllSets = function () {
var selectedCollectionSets = $scope.selectedCollection.sets;
for (var set in selectedCollectionSets) {
if (selectedCollectionSets[set].isSelected == false) {
$scope.repetitionService.addSet(set);
}
selectedCollectionSets[set].isSelected = true;
}
};
$scope.deselectAllSets = function () {
var selectedCollectionSets = $scope.selectedCollection.sets;
for (var set in selectedCollectionSets) {
if (selectedCollectionSets[set].isSelected) {
$scope.repetitionService.removeSet(set);
}
selectedCollectionSets[set].isSelected = false;
}
};
$scope.startRepetition = function () {
$location.path("/repetition");
};
}
function RepetitionController($scope, $location, repetitionService) {
$scope.sets = repetitionService.getSets();
$scope.questionsLeft = $scope.sets.length;
$scope.questionsAnswered = 0;
$scope.percentageLeft = ($scope.questionsLeft == 0 ? 100 : 0);
$scope.endRepetition = function () {
$location.path("/setsAndCollections");
};
}
now I am in process of converting global function controllers to ones defined by angular API as you can see by example of DashboardController
.
Now in my test:
describe("DashboardController", function () {
var ctrl, scope;
beforeEach(inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
ctrl = $controller('DashboardController', {$scope: scope});
}));
it("has repeats attribute set to 5", function () {
expect(scope.repeats).toBe(5);
});
});
I am getting
Error: Argument 'DashboardController' is not a function, got undefined
I am wondering then, where is my mistake? If I understand this right, ctrl = $controller('DashboardController', {$scope: scope});
should inject my newly created scope to my DashboardController
to populate it with attributes - in this case, repeats
.
Load the Angular App beforeEach(module('MyApp')); //3. Describe the object by name describe('compute', function () { var compute; //4. Initialize the filter beforeEach(inject(function ($filter) { compute = $filter('compute', {}); })); //5. Write the test in the it block along with expectations.
The controller in AngularJS is a JavaScript function that maintains the application data and behavior using $scope object. You can attach properties and methods to the $scope object inside a controller function, which in turn will add/update the data and attach behaviours to HTML elements.
AngularJS is written with testability in mind, but it still requires that you do the right thing. We tried to make the right thing easy, but if you ignore these guidelines you may end up with an untestable application.
You need to set up your Prototype module first.
beforeEach(module('Prototype'));
Add that to your test, above the current beforeEach
would work.
describe("DashboardController", function () {
var ctrl, scope;
beforeEach(module('Prototype'));
beforeEach(inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
ctrl = $controller('DashboardController', {$scope: scope});
}));
it("has repeats attribute set to 5", function () {
expect(scope.repeats).toBe(5);
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With