Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit Testing AngularJS module controller

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.

like image 446
arthurakay Avatar asked Mar 08 '13 19:03

arthurakay


People also ask

What is unit testing in AngularJS?

Testing in AngularJS is achieved by using the karma framework, a framework which has been developed by Google itself. The karma framework is installed using the node package manager. The key modules which are required to be installed for basic testing are karma, karma-chrome-launcher ,karma-jasmine, and karma-cli.

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.

How pass data from controller controller to AngularJS?

Approach: To share data between the controllers in AngularJS we have two main cases: Share data between parent and child: Here, the sharing of data can be done simply by using controller inheritance as the scope of a child controller inherits from the scope of the parent controller.


1 Answers

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

like image 162
dnc253 Avatar answered Sep 23 '22 18:09

dnc253