5

I'm looking at the TODO MVC AngularJS example, and I see the application is defined as a module.

var todomvc = angular.module('todomvc', []);

Inside the controllers, I see them defined as:

todomvc.controller('TodoCtrl', function TodoCtrl($scope, $location, todoStorage, filterFilter) {
    //...
});

My question deals with unit testing... how do I write a unit test for that class?

I've tried things like:

describe('TodoCtrl', function () {
    var controller;

    beforeEach(function () {
        controller = todomvc.TodoCtrl;
    });

    afterEach(function() {
        controller = null;
    });

    describe('addTodo() method', function() {
        console.log(controller)
        it('should do something', function () {
            expect(typeof controller.addTodo).toBe(true); //should fail
        });

    });
});

...but then "controller" ends up being null or undefined.

Do I need to modify the TODO MVC app so that the function passed to todomvc.controller() isn't anonymous?

Any direction would be appreciated as I'm very new to Angular.

1 Answer 1

10

You need to used the $controller service to unit test the controller.

Basically, you do something like this:

var scope, ctrl;

beforeEach(inject(function($rootScope, $controller) {
  scope = $rootScope.$new();
  ctrl = $controller('TodoCtrl', {$scope: scope});
}));

//use scope and ctrl as needed

See the example here: https://github.com/angular/angular-phonecat/blob/master/test/unit/controllersSpec.js#L18

Sign up to request clarification or add additional context in comments.

4 Comments

That example does help a great deal... but I still get a "TodoCtrl is not defined" error, which makes me think I need to change the way in which the controller in the TODO MVC example is written (making it more like the example you linked). But I'm on the right track, thanks!
Upon further inspection, I have to use "scope.addTodo()" instead of "ctrl.addTodo()" after using your suggestion. Thanks!
In my case I had to add quotes around the controller name: ctrl = $controller('TodoCtrl', {$scope: scope});
When using a global function as a controller, you don't need quotes, but using quotes should work for the global function and when registering the controller via the controller module function. I've updated the answer to use quotes. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.