Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angularjs - testing controller

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.

like image 982
Andna Avatar asked Apr 03 '13 23:04

Andna


People also ask

How do I run a unit test in AngularJS?

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.

What is AngularJS controller?

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.

Is AngularJS code unit testable?

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.


1 Answers

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);
  });
});
like image 98
Xesued Avatar answered Oct 06 '22 00:10

Xesued