angularjs - testing controller

angularjs, unit-testing

Solution

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);
  });
});

Problem

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`.

Original source