3

I want to stub a internal function in my code when unit testing it, example:

//foobar.js
const uuid = require('uuid');

function foo() {
    console.log('uuid: ' + uuid.v4());
    // Lots of timers
}
exports._foo = foo;

function bar() {
    //Logic...
    foo();
    //Logic...
}
exports.bar = bar;

And the unit test:

// test/foobar.js
const chai = require('chai'),
    expect = chai.expect,
    proxyquire = require('proxyquire'),
    sinon = require('sinon');

describe('bar', () => {
    it('call foo', () => {
        let foo = proxyquire('./foo.js', {
                uuid: {
                    v4: () => {
                        return '123456789';
                    }
                }
            }),
            fooSpy = sinon.spy(foo._foo);

        foo.bar();
        expect(fooSpy.calledOnce);
    });
});

Now, when unit testing bar, I can spy on foo just fine, and it is quite fine.
However, the real foo make a lot of time consuming calls (DB calls, file IO...), and while I could use proxyquire to stub all fs and db calls to terminate immediately, that would duplicate code from the test of foo, be unreadable, and being bad altogether.

The simple solution would be to stub foo, but proxyquire doesn't seems to like that. A naive foo._foo = stubFoo didn't worked either. Rewire doesn't seems to handle this either.

What I could do would be to make a file that import and export foobar.js, and use proxyquire on it, but the idea itself is already bad.

How can I stub the foo function when testing bar?

DrakaSAN
  • 7,673
  • 7
  • 52
  • 94

1 Answers1

0

Sinon is perfectly capable to handle this if done correctly, you just need to remember sinon replace references in the object, and export is not where the function is declared. But with the same code and tests, a simple modification to bar make it works:

function bar() {
    //Logic...
    exports._foo();
    //Logic...
}
DrakaSAN
  • 7,673
  • 7
  • 52
  • 94