0
votes

I'm using Karma, Jasmine and Sinon to test an AngularJs app. A controller has a service injected and I want to use the Sinon sandbox to stub a method on the service. Here is the controller:

(function () {
    'use strict';

    angular.module('app').controller('myController', myController);

    myController.$inject = ['$scope', 'myService'];

    function myController($scope, myService) {

        $scope.methodTestResult = myService.testMethod();
    }
}());

And here is the test file:

(function () {
    'use strict';

    beforeEach(module('app'));

    describe('myController', function () {

        var $scope, myService;

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

            myService = _myService_;

            $controller('myController', { $scope: $scope });

            sandbox = sinon.sandbox.create();

        }));

        afterEach(function () {
            sandbox.restore();
        });

        describe('methodTestResult', function () {

            beforeEach(function () {
                sandbox.stub(myService, 'testMethod');
            });

            it('invokes the testMethod', function () {
                expect(myService.testMethod).toHaveBeenCalled();
            });
        });
    });

}());

FWIW, here is the service factory:

(function () {
    'use strict';

    angular.module('app').factory('myService', myService);

    function myService() {  
        return {
            testMethod: function () {
                return true;
            }
        };
    }
}());

When I run the test it fails and says:

Expected spy "testMethod" to have been called. "testMethod" was called 0 times.

Weirdly, if I add a test property to the service from inside the test file, e.g:

myService.testProperty = 'test';

And then log this out from within the controller being tested:

console.log(myService.testProperty);

This works as expected and I can see the new property added in the test file inside the controller. I have sinon specified as a framework in my karma configuration, no errors are thrown regarding missing dependencies. Here are the packages I have installed:

"grunt": "^0.4.5"
"grunt-karma": "^0.12.1",
"jasmine-core": "^2.4.1",
"jasmine-sinon": "^0.4.0",
"karma": "^0.13.19",
"karma-jasmine": "^0.3.6",
"karma-phantomjs-launcher": "^0.2.3",
"karma-sinon": "^1.0.4",
"phantomjs": "^1.9.19",
"sinon": "^1.17.2"

I've used this same AngularJs/Karma/Jasmine/Sinon combination before and everything has worked as expected. Unsure why the stub isn't being called?

1

1 Answers

1
votes

At this point

       $controller('myController', { $scope: $scope });

'myController' constructor function had already been called, and so original myService.testMethod method. The solution is to stub it before controller instantiation.