Search code examples
javascriptkarma-jasminespyon

spyon doesn't work with nested function in a non angularjs environment


I'm having a problem to spyon a function that is called from another function in my javascript module (no angularJS)

this is the javascript module:

var Utils = function () {

function getFunction1(value1) {
    var value2 = getFunction2();

    return value1 + value2;
};

function getFunction2() {

    return 10;
};

return {
    getFunction1: getFunction1,
    getFunction2: getFunction2
};
};

my test is:

describe('test spyon', function () {

var myApp = new Utils();
it('test spyOn', function () {

    spyOn(myApp, 'getFunction2').and.returnValue(2);

    // call a function under test and assert
    expect(myApp.getFunction1(1)).toBe(3);
});
});

I run the command:

gradle build karma

And the result is:

    PhantomJS 1.9.8 (Windows 7 0.0.0) test spyon test spyOn FAILED
Expected 11 to be 3.
Error: Expected 11 to be 3.
    at X:/projects/ETRANS-CALCULATOR/branches/ONS128-ONS129-LifeIPCalculators/Common/src/test/webapp/unit/utilsSpec.js:30
    at X:/projects/ETRANS-CALCULATOR/branches/ONS128-ONS129-LifeIPCalculators/Common/node_modules/karma-jasmine/lib/boot.js:126
    at X:/projects/ETRANS-CALCULATOR/branches/ONS128-ONS129-LifeIPCalculators/Common/node_modules/karma-jasmine/lib/adapter.js:171
    at http://localhost:9876/karma.js:182
    at http://localhost:9876/context.html:67
PhantomJS 1.9.8 (Windows 7 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.946 secs / 0.002 secs)
:Common:karma FAILED

If I do the same test in an AngularJS controller it will work using $scope instead of myApp

Any help?


Solution

  • The getFunction2 referenced in getFunction1 is the scoped function getFunction2, not myApp's instance of getFunction2. The spy is spying on the instance's getFunction2 though.

    To fix this, you should use this.getFunction2 in getFunction1 rather than getFunction2.

    i.e.

    function getFunction1(value1) {
        var value2 = this.getFunction2();
    
        return value1 + value2;
    };