1

I am trying to test my AngularJS controller function using Jasmine. However, I am getting TypeError: undefined is not a function.

This is what the test looks like:

describe('BoardController', function() {

    beforeEach(module('examtesting'));

    var BoardController;

    beforeEach(inject(function($rootScope, $controller) {

        var scope = $rootScope.$new();

        BoardController = $controller('BoardController', { 
            $scope: scope,
            board: null,
            BoardService: null
        });

    }));


    it ("should toggle create_active", function() {
        var category = { create_active: false }

        BoardController.toggleCreateActive(category);

        expect(category.create_active).toBe(true);
    });

});

And here's the function I am trying to test:

    $scope.toggleCreateActive = function(category) {
        category.create_active = !category.create_active;
    }

What am I doing wrong?

0

3 Answers 3

3

Like it says in the last listing toggleCreateActive is a function on the $scope. You cannot reference it as BoardController.toggleCreateActive. Instead make the scope var available for tests (move the declaration out of beforeEach) and call scope.toggleCreateActive().

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

Comments

2

This should work:

describe('BoardController', function() {

    beforeEach(module('examtesting'));

    var createController, scope;

    beforeEach(inject(function($rootScope, $controller) {
        scope = $rootScope.$new();

        createController = function() {
            return $controller('BoardController', { 
                $scope: scope,
                board: null,
                BoardService: null
            });
        };
    }));


    it ("should toggle create_active", function() {
        var category = { create_active: false },
            controller = createController();

        scope.toggleCreateActive(category);

        expect(category.create_active).toBe(true);
    });

});

Comments

-1

When you use $scope, all your model is on scope, and the controller is just the controller...

Testing controller with controllerAs

After we’ve seen how to test a service, let’s talk about testing a controller.

function MyController(MyService) {
 this.greetUpperCase = function(name) {
  return MyService.greet(name).toUpperCase();
 }
}

We’d like angular’s DI to inject an instance of our controller to our test, but controllers are not singltons as services.

Therefore, we will:

inject the $controller service use it to instance a controller for us

var $controller;
beforeEach(module('MyModule'));
beforeEach(inject(function(_$controller_) {
    $controller = _$controller_; })
);
it('test greetUpperCase()', function() {
    var ctrl = $controller('MyController');
    expect(ctrl.greetUpperCase('bob')).toBe('HELLO BOB');
});

https://jsfiddle.net/ronapelbaum/tcmsw688/

Testing controller with $scope

Now, if you’re still workng with $scope:

function MyController($scope, MyService) {
 $scope.greetUpperCase = function(name) {
  return MyService.greet(name).toUpperCase();
 }
}

Basically, when you’re working with $scope, you don’t really care about the controller itself, since it’s doing everything on it’s scope.

So, we will need to:

inject $rootScope create a new scope inject it to a new controller test the $scope

it('test greetUpperCase()', function() {
 var myScope = $rootScope.$new();
 $controller('MyController', {
  $scope: myScope
 });
 expect(myScope .greetUpperCase('bob')).toBe('HELLO BOB');
});

https://jsfiddle.net/ronapelbaum/pkhaxmdg/

1 Comment

Excessive promotion of a specific product/resource may be perceived by the community as spam. Take a look at the help center, specially What kind of behavior is expected of users?'s last section: Avoid overt self-promotion. You might also be interested in How do I advertise on Stack Overflow?.

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.