Search code examples
node.jsmocha.jsrequiresinonchai

Spying on function within a function


I have some code that looks like this, in a file called logger.ts

(function (logger) {
logger.getLogger = function () {
    var log4js = require('log4js');
    log4js.configure(__dirname + "/../log4js-config.json");
    var logger = log4js.getLogger(require('path').basename(__filename));
    return logger;
};
})(module.exports);

Now, the logger that gets returned here is an object that contains methods such as 'info' and 'error'. I want to spy on these methods and assert that they were called with certain parameters.

I use this code in other classes and want to mock and spy on the 'error' and 'info' methods. I have therefore written this in my test

var loggerStub = require('logger');
sinon.spy(loggerStub.getLogger, 'info');

it("should log the query", function() {
            var spyCall = loggerStub.info.getCall(0);
            expect(spyCall.args[0]).deep.equal("error: " + somethingVariable);
        });

Running this gives me the error:

Attempted to wrap undefined property info as function.

What am I doing wrong?


Solution

  • You are spying on a property (info) of your own function (getLogger) which you never set instead of the log4js.info.

    A fast way (not sure if thats good for you) to solve this, is to actually create the logger and spy in the returned objects info method:

    var logger = require('logger').getLogger(); // be aware that an actual logger is created!
    sinon.spy(logger, 'info');
    
    it("should log the query", function() {
                var spyCall = logger.info.getCall(0);
                expect(spyCall.args[0]).deep.equal("error: " + somethingVariable);
            });