1

I'm trying to test function calls from my controller's init function. I route various logic based on stateParams and want to write unit tests against this scenarios but I'm having trouble getting it working.

My init function

    var _init = function () {
        // Get full companyList
        servicecall().then(function (response) {

            if ($stateParams.ID) {
                $scope.callOne();
            }
            else if ($stateParams.Index == -1) {
                $scope.callTwo();
            }
            else if ($stateParams.Index == '' || $stateParams.Index == null) {
                $scope.callThree();
            }
            else
                $scope.callFour();
        },
        function (err) {
            console.log(err);
        });
    };
    _init();

So simply I want to set $stateParams.Index = -1, and make sure callTwo() gets called.

My beforeEach looks like

    beforeEach(function () {

        controller = $controller('Controller', {
            $scope: $scope,
            $stateParams: $stateParams,
            $state: $state
        });

        // And add $scope's spyOns
        spyOn($scope, 'callOne').and.callThrough();
        spyOn($scope, 'callTwo').and.callThrough();
        spyOn($scope, 'callThree').and.callThrough();
        spyOn($scope, 'callFour').and.callThrough();
    });

At first I tried the below, which of course did not work; it says spy was not called.

        it("should call callTwo if stateParams.index is -1", function () {
            $stateParams.Index = -1;
            expect($scope.callTwo()).toHaveBeenCalled();
        });

I figured that all of the init was happening before my spy attached, so then I tried moving that stuff inside of my it call but everything broke down.

This one says callTwo has already been spied upon.

    it("should call callTwo if stateParams is -1", function () {
            $stateParams.Index = -1;
            spyOn($scope, 'callTwo').and.callThrough();

            controller = $controller('Controller', {
                $scope: $scope,
                $stateParams: $stateParams,
                $state: $state
            });

            expect($scope.callTwo).toHaveBeenCalled();
        });

But if I move the spy declaration after the controller is initialized it says it's not called again

  1. How can I ensure calls are being made as expected during a controller instantiation?

1 Answer 1

1

Not sure if it's the best solution, but currently nothing else comes to mind and this definitely works.

You can have a describe for every such test, since the $stateParams are injected when you create your controller. That's why doing it inside the it is not sufficient since the $scope at that time belongs to the controller already created.

So you need to have:

describe('Controller tests for when Index === -1', function () {

    beforeEach(function (...) {

        $stateParams.Index = -1; 

        controller = $controller('Controller', {
             $scope: $scope,
             $stateParams: $stateParams,
             $state: $state
        });
    }

    // it tests for Index === -1 case
});

So in this example all of the it tests you'll have are guaranteed to have $stateParams === 1. Same will go for your other values.

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

Comments

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.