_foo is not a function, when called from init method in Jasmine

时间:2015-06-15 14:22:42

标签: javascript jasmine

I am testing a controller which has a private method _init() called during its instantiation.

It does some service calls (which are mocked out) and calls some private helper functions within the same controller. It all works great up until within a success block of a service call it tries to call a helper function, where I then get the error that _setPersonDropdown is not a function

I understand I cannot call private functions directly, but shouldn't intra-controller calls be fine even when they're private?

Controller

var _init = function () {
        // Get PersonType list for dropdown
        personService.getPersonTypeList().success(function (response) {
            $scope.personTypeList = response;
            _setPersonDropdown();   //<-- this is the line that errors
        })
        .error( function (err) {
            console.log(err);
        });
    };
    _init();

Tests

beforeEach(inject(function($controller, $q) {
        personService = {
            getPersonTypeList: function () {

                var expectedResponse = [];

                return {
                    then: function (successFn) {
                        successFn(expectedResponse);
                    },
                    success: function (fn) {
                        fn(expectedResponse);
                    },
                    error: function (fn) {
                        fn(expectedResponse);
                    }
                };
            }
        };
    }));

controller = $controller('personController', {
            $scope: $scope,
            $stateParams: $stateParams,
            personService: personService
});

1) Why is it saying _setPersonDropdown is not a function when it's definitely defined within the Controller

var _setPersonDropdown = function () {
   // do some stuff
};

... full controller for reference, as requested

angular.module('myApp')

    .controller(definition and injections, function (...) {

        var _init = function () {
            // ...some random setup code

            // Get PersonType list for dropdown
            personService.getPersonTypeList().success(function (response) {
                $scope.personTypeList = response;
                _setPersonDropdown();    //<--- the error
            })
            .error( function (err) {
                console.log(err);
            });
        };
        _init();

        var _setPersonDropdown = function () {
            //do the thing
        };
});

1 个答案:

答案 0 :(得分:2)

Make sure you're calling _init() after you define _setPersonDropdown(), or (my preferred approach) just use function declarations instead of var definitions for functions this way it will be hoisted.

So for example this would be wrong

var _init = function () {
    // Get PersonType list for dropdown
    personService.getPersonTypeList().success(function (response) {
        $scope.personTypeList = response;
        _setPersonDropdown();   //<-- this is the line that errors
    })
    .error( function (err) {
        console.log(err);
    });
};
_init();

var _setPersonDropdown = function() { /* ... */ };

While this would work

var _init = function () {
    // Get PersonType list for dropdown
    personService.getPersonTypeList().success(function (response) {
        $scope.personTypeList = response;
        _setPersonDropdown();   //<-- this is the line that errors
    })
    .error( function (err) {
        console.log(err);
    });
};
_init();

function _setPersonDropdown() { /* ... */ }