Search code examples
javascriptfunctionunit-testingsinonstub

stub a private function using sinon


I would like to stub a function that is not exposed by the given file.

My code is as follows:

const inner = function inner(){
    return Math.random()
}

const outer = function outer(){
    if (inner()>0.5)
        return true
    return false
}

module.exports = {
    outer,
}

To test the outer method, i need to stub the inner method. what I tried so far:

const sinon = require('sinon')
const fileToBeTested = require('./my-tiny-example')

sinon.stub(fileToBeTested, 'inner')
     .returns(0.9)
console.log(fileToBeTested.outer())

The error I'm getting:

TypeError: Cannot stub non-existent property inner

Any suggestion given that I'm using sinon for stubbing.

Thanks


Solution

  • You could use rewire package to stub inner function without exporting it.

    E.g.

    my-tiny-example.js:

    const inner = function inner() {
      return Math.random();
    };
    
    const outer = function outer() {
      if (inner() > 0.5) return true;
      return false;
    };
    
    module.exports = {
      outer,
    };
    

    my-tiny-example.test.js:

    const rewire = require('rewire');
    const sinon = require('sinon');
    
    describe('64741353', () => {
      it('should return true', (done) => {
        const mod = rewire('./my-tiny-example');
        const innerStub = sinon.stub().returns(1);
        mod.__with__({
          inner: innerStub,
        })(() => {
          const actual = mod.outer();
          sinon.assert.match(actual, true);
          done();
        });
      });
      it('should return true', (done) => {
        const mod = rewire('./my-tiny-example');
        const innerStub = sinon.stub().returns(0);
        mod.__with__({
          inner: innerStub,
        })(() => {
          const actual = mod.outer();
          sinon.assert.match(actual, false);
          done();
        });
      });
    });
    

    unit test result:

      64741353
        ✓ should return true (68ms)
        ✓ should return true
    
    
      2 passing (123ms)
    
    --------------------|---------|----------|---------|---------|-------------------
    File                | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    --------------------|---------|----------|---------|---------|-------------------
    All files           |   85.71 |      100 |      50 |   83.33 |                   
     my-tiny-example.js |   85.71 |      100 |      50 |   83.33 | 2                 
    --------------------|---------|----------|---------|---------|-------------------