How to mock a function inside another function (which I am testing) using sinon?

Ravi Shankar picture Ravi Shankar · Feb 9, 2017 · Viewed 9.4k times · Source

let's say i have a function

Func a() {
    //Do Something
    let c = b();
    return c;
}

I want to test the function a and mock b() and in the mock want to assign c. Sinon.Stub(Test,"b").returns("DummyValue"); c should be assigned DummyValue.

How can I do that?

describe("a", () => {
    let a = a();
    //mock b();
    action = execute(a);
    expect(action).should.return.("DummyValue");
})

Answer

Ravi Shankar picture Ravi Shankar · Feb 9, 2017

When we have 2 functions in the same file and want to stub one of them and test the other. For example,: Test: tests.js

let ComputeSumStub = sinon.stub(OfflineLoader, "ComputeSum");
const ans = function ()
{
    return 10;
};
ComputeSumStub.returns(ans);
const actualValue: number = OfflineLoader.sum();
expect(actualValue).to.be.equal(10);

Dev: foo.js

function sum(): number
{
    return ComputeSum(8, 9);
}

function ComputeSum(a: number, b: number): number
{
    return a + b;
}

We cannot do that, because after compilation the functions are exported with different signatures, with full name and while stubbing we stub the global function but while calling it from within the other function, we call the local function, hence it doesn’t work. There is a workaround to do that.

foo.js
const factory = {
  a,
  b,
}
function a() {
  return 2;
}

function b() {
  return factory.a();
}

module.exports = factory;

test.js

const ser = require('./foo');
const sinon = require('sinon');

const aStub = sinon.stub(ser, 'a').returns('mocked return');
console.log(ser.b());
console.log(aStub.callCount);

Ref: Stubbing method in same file using Sinon