javascriptnode.jsunit-testingmocha.jsspy

Writing a unit test to check if a module inside a module is being called - Node.js


I am trying to write a unit test for a module that calls another function - as a module - within it. The test is to check if the imported function is being called when the main module is called.

I've been using Mocha and Chai. I've also tried different approaches with Sinon and Proxyquire.

These are the modules and most recent test attempt:

functionModule.js

module.exports = (param) => {
let somethingOld;
if (param) { 
somethingOld = param; 
}

return somethingOld
}

mainModule.js

const functionModule = require('./functionModule');

module.exports = (param1, param2) => {

 const somethingNew = functionModule(argument);

return {somethingNew}
}

mainModule.test.js

const mainModule = require('../mainModule.js');

describe('test mainModule', () => {
 it('test functionModule is called', () => {
   const getModuleSpy = chai.spy.on(mainModule, 'functionModule');

   mainModule(argument1, argument2);
  
   expect(getModuloSpy).to.have.been.called();
 })
})

I am mostly getting "AssertionError: expected { Spy 'object.functionModule' } to have been called".


Solution

  • You can use sinon using the stub method to copy the original function in the main function. Then you can use chai using expect to validate that the function in the main function is being called. First, you need to refactor your functionModule.js about way to exported it:

    const send = (param) => {
      let somethingOld;
      if (param) { 
        somethingOld = param; 
      }
    
      return somethingOld;
    }
    
    module.exports = { send: send }
    

    Also fix your mainModule.js:

    const functionModule = require('./functionModule');
    
    module.exports = (param1, param2) => {
      const somethingNew = functionModule.send(argument);
    
      return {somethingNew}
    }
    

    Then fix your test file like this:

    const mainModule = require('../mainModule.js');
    const functionModule = require('../functionModule');
    const sinon = require('sinon');
    const { expect } = require('chai');
    
    describe('test mainModule', () => {
     it('test functionModule is called', () => {
       const stubFunctionModule = sinon.stub(functionModule, 'send').returns(true);
    
       mainModule(argument1, argument2);
      
       expect(stubFunctionModule.calledOnce).to.be.true;
     })
    })
    

    Make sure the variable argument1 and argument2 are defined by value. Pretend the stub function returns the true result value. Take a look at the Chai documentation to see the calledOnce method to verify that the stub function has been called correctly.

    I hope this helps you.

    Regards