3
votes

I'm new Sinon. i'm unable to spy the private ajax function

Actual code in library.js

function ajax () {
    console.log("I'm a");
}

function getJSON() {
    ajax();
    console.log("I'm b");
}

exports.getJSON = getJSON;

Actual Test Code

var sinon = require('sinon');
var lib = require('./library');

describe('Tutor Test', function () {
    it('getJSON Calling ajax', function (done) {
        var ajax = sinon.spy(lib, 'ajax');
        lib.getJSON();

        ajax.restore();
        sinon.assert.calledOnce(ajax);
        done();
    });
});

Note: I already tried with below object example. it works like charm.

Working Code in library.js

var jquery = {
    ajax: function () {
        console.log("I'm a");
    },

    getJSON: function () {
        this.ajax();
        console.log("I'm b");
    }
};

exports.jquery = jquery;

Working Test Cases.

var sinon = require('sinon');
var $ = require('./library').jquery;

describe('Tutor Test', function () {
    it('getJSON Calling ajax', function (done) {
        var ajax = sinon.spy($, 'ajax');
        $.getJSON();

        ajax.restore();
        sinon.assert.calledOnce(ajax);
        done();
    });
});

I'm getting error like below during mocha test

1) Tutor Test getJSON Calling ajax:
     TypeError: Attempted to wrap undefined property ajax as function
      at Object.wrapMethod (node_modules/sinon/lib/sinon/util/core.js:113:29)
      at Object.spy (node_modules/sinon/lib/sinon/spy.js:41:26)
      at Context.<anonymous> (test.js:41:26)
1
It's not working in the first case because there's no function ajax exported in your library.js - Vsevolod Goloviznin
yes i know. that is the question without exporting ajax` which is not required for application but needed for test case.` - Sachin
Sinon will not work in this case as you expect it - Vsevolod Goloviznin
so sinon does not work for functional code - Sachin
@Boss first in your example, that's not functional code, that's procedural code, and it will not work because ajax function is private to the library.js module. - Hosar

1 Answers

4
votes

As far as i know, Spying private Variables / Function is not possible in Sinon. So avoid using Sinon for those use cases.

Note: Your (ajax) function does not have param and return value and not bind to the exported object is real challenge for sinon

In such case, If you wanted to make sure whether ajax function is triggered or not. You can use rewire.

Below is the working code.

var rewire = require('rewire');
var lib = rewire('./library');
const assert = require('assert');

describe('Tutor Test', function () {
    it('getJSON Calling ajax', function (done) {
        lib.__set__('isAjaxCalled', false);
        lib.__set__('ajax', function () {
            lib.__set__('isAjaxCalled', true);
        });

        lib.getJSON();
        assert.equal(lib.__get__('isAjaxCalled'), true);
        done();
    });
});

No Change your Actual code, library.js