Peter Graham
Peter Graham

Reputation: 2575

Unit Testing a Controller in Angular.js

I'm following the Angular tutorial on how to unit test a controller. I'm using Karma and Jasmine for testing. When I run the test, I get

Error: [ng:areq] Argument 'testController' is not a function, got undefined

Any ideas of how I can load the testController in test.js? Code below. Thanks!

<!-- app.js --> 

var simulatorApp = angular.module('simulatorApp', ['ngRoute', 'ngResource', 'ngCookies'],

simulatorApp.config(['$routeProvider', function($routeProvider) {
    $routeProvider
        .when('/', {templateUrl: '/angular/views/home.html', controller: homeController})
        .when('/test', {templateUrl: '/angular/views/test.html', controller: testController})
        .otherwise({redirectTo: '/'});
}]);

<!-- testController.js -->

function testController($scope) {
    $scope.password = '';
    $scope.grade = function () {
        var size = $scope.password.length;
        if (size > 8) {
            $scope.strength = 'strong';
        } else if (size > 3) {
            $scope.strength = 'medium';
        } else {
            $scope.strength = 'weak';
        }
    };
}

<!-- test.js -->
describe('testController', function() {
    beforeEach(module('simulatorApp'));

    var $controller;

    beforeEach(inject(function (_$controller_) {
        // The injector unwraps the underscores (_) from around the parameter names when matching
        $controller = _$controller_;
    }));

    describe('$scope.grade', function () {
        it('sets the strength to "strong" if the password length is >8 chars', function () {
            var $scope = {};
            var controller = $controller('testController', {$scope: $scope});
            $scope.password = 'longerthaneightchars';
            $scope.grade();
            expect($scope.strength).toEqual('strong');
        });
    });
})

Upvotes: 0

Views: 464

Answers (2)

mengstrom
mengstrom

Reputation: 233

Here's a working plunkr.

As Narek Mamikonyan answered you haven't registered your controller on your module.

simulatorApp.controller('testController', testController);

function testController($scope) {
    ...
};

Same problem likely with homeController

simulatorApp.controller('homeController', homeController);

function homeController($scope) {
    ...
};

Besides, you should try and declare your controller something like this as this won't explode if you have minification on your javascript files

simulatorApp.controller('testController', ['$scope', testController]);

If you don't, $scope won't be the same once minified and your app won't work.

Upvotes: 1

Narek Mamikonyan
Narek Mamikonyan

Reputation: 4611

you didn't defined your controller in module

simulatorApp.controller('testController', function testController($scope) {
    $scope.password = '';
    $scope.grade = function () {
        var size = $scope.password.length;
        if (size > 8) {
            $scope.strength = 'strong';
        } else if (size > 3) {
            $scope.strength = 'medium';
        } else {
            $scope.strength = 'weak';
        }
    };
})

Upvotes: 0

Related Questions