Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

stubbing a function in a proxyquired object

I want to unit-test the following simplified module:

const Logger = require('logplease');
const logger = Logger.create('utils');

const tester = {

    one: () => {
        logger.log('called real one()');
        tester.two();
    },
    two: () => {
        logger.log('called real two()');
    },
};

module.exports = {
    one: tester.one,
    two: tester.two
};

I'm replacing the external dependency logplease using Proxyquire, which works very well. However I need to stub two() because I want to unit-test one() while eliminating the side-effects two() produces when it runs in real code.

it.only('stubbing functions on the "proxyquired" object under test', function(done) {

    const loggerStub = {
        create: () => {
            return { log: (msg) => { console.log('fake logger: ', msg); } };
        }
    };

    let tester = proxyquire('../tester', { 'logplease': loggerStub });

    let stub2 = sinon.stub(
        tester, 
        'two', 
        () => { 
            console.log('called fake stub of two()'); 
        }
    );

    tester.one();

    console.log('call count 2: ', stub2.callCount);
    done();
});

Output I get:

fake logger:  called real one() 
fake logger:  called real two() 
call count 2: 0

Output I expect:

fake logger:  called real one() 
called fake stub of two()
call count 2: 1

Why doesn't my stub function run?

like image 610
montrealist Avatar asked Feb 10 '17 21:02

montrealist


People also ask

What is stubbing in Javascript?

What are Stubs? A test stub is a function or object that replaces the actual behavior of a module with a fixed response. The stub can only return the fixed response it was programmed to return.

What is proxyquire in nodejs?

Proxies nodejs's require in order to make overriding dependencies during testing easy while staying totally unobtrusive. If you want to stub dependencies for your client side modules, try proxyquireify, a proxyquire for browserify v2 or proxyquire-universal to test in both Node and the browser.


1 Answers

Short answer:

const Logger = require('logplease');
const logger = Logger.create('utils');

const tester = {

    one: () => {
        logger.log('called real one()');
        tester.two();
    },
    two: () => {
        logger.log('called real two()');
    },
};

module.exports = tester;

Explanation: scope

You exported one and two as:

module.exports = {
    one: tester.one,
    two: tester.two
};

In this case tester.one knows only about this function:

two: () => {
    logger.log('called real two()');
}

and have no idea about stubbed two. So you have two versions of two, just try to invoke tester.two() inside test.

like image 194
Nazar Sakharenko Avatar answered Nov 07 '22 10:11

Nazar Sakharenko