Search code examples
node.jsunit-testingtestingsinon-chai

Sinon stub method calling from another file


I'm trying to set up unit tests in my project. For that, I use mocha chai and sinon librairies. I'm using a NodeJs server version 8.

Versions :

Sinon : "7.1.0" Mocha: "5.1.0" Chai: "4.2.0"

I'd like to stub a method which is declared in another file.

Here's an example :

- a.js
   exports.FnA(return FnB())
- b.js
   exports.FnB()

I want to stub method FnB() from b.js file so I can test FnA() regardless FnB() return.

Here's what I've tried :

beforeEach(() => {
            this.FnBStub = sinon.stub(b, 'FnB').returns('mocked');
        });

afterEach(() => this.FnBStub.restore());

it('should mocked FnB function', () => {
            try {
                console.log(b.FnB()); //returns 'mocked'
                console.log(a.FnA()); //return error from FnB() execution ...
            } catch (e) {
                console.log(e);
            }
        });

It does stub the method FnB() but only when I called it from an instance of b file. So when I called FnA() the stub seems to go away ...

What am I missing ?

Some help would be really appreciated, thanks :)

EDIT :

a.js example :

const FnB = require('./FnB)

exports.FnA = data => {
    const limit = data.releases.update ? 60 : 20;
    return FnB(data.ref, limit)
};

b.js example :

exports.FnB = (ref, page, query) => {
   //API call
}

testFile.js example :

const a = require('../a')
const b = require('../b')

beforeEach(() => {
            this.FnBStub = sinon.stub(b, 'FnB').returns('mocked');
        });

afterEach(() => this.FnBStub.restore());

it('should mocked FnB function', () => {
            try {
                console.log(b.FnB()); //returns 'mocked'
                console.log(a.FnA()); //return error from FnB() execution ...
            } catch (e) {
                console.log(e);
            }
        });

So as I said I'd like to stub this FnB calling method and just check if this method is called with right parameters.


Solution

  • If the module being exported is a function itself and not a part of an object, you can't stub it directly.

    You need to use something like proxyquire. Your test code will look something like this:

    const FnBstub = sinon.stub();
    const proxyquire = require('proxyquire');
    const a = proxyquire('../a', {
        FnB: FnBstub
    });
    const b = require('../b');
    

    For more info, look here: https://github.com/sinonjs/sinon/issues/664