'Sinon Spy / Stub for Function inside Function (Private Function)
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)
Solution 1:[1]
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 forsinon
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
Solution 2:[2]
Call your method from the exported public API.
var jquery = {
ajax: function () {
console.log("I'm a");
},
getJSON: function () {
//this.ajax();
jquery.ajax(); // <---
console.log("I'm b");
}
};
Another approach is to call console.log with a hint, and then spy on the log.
ajax: function () {
console.log("I'm a");
},
var ajax = sinon.spy(console, 'log');
$.getJSON();
sinon.assert.calledOnceWithExactly("I'm a")
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Venkat.R |
Solution 2 |