简体   繁体   中英

When unit testing a class method, how do I mock a function it calls--one defined in an imported module?

I am unit testing a particular method, and am having issues mocking another function that is called during the process. In my case, the method to test is defined in a class, and the function I'd like to mock is defined in a separate module. How do I mock this function? See below for my code.

In the past, I've used the Sinon package to mock/stub a dependency ( example ). But that doesn't work in this case. This is the first time I'm testing a method defined in a class, so perhaps that's why mocking the dependency isn't working.


My Code

Module Containing Test Function (myLib/myDir/combo.js)

const { externalFunction } = require('./external-function')
class Combo {
  constructor(props) {}
  async myMethod () {// The function under test.
    externalFunction()
  }
}
const myCombo = props => new Combo(props)
module.exports = { myCombo }

My Test File (test/myLib/myDir/combo.test.js); no attempt at mocking

const { myCombo } = require('../../../myLib/myDir/combo')

const comboObj = myCombo({}) // Instantiate object to expose method to test.
await comboObj.myMethod()// Call method that I want to test.  This throws type error because myMethod function calls externalFunction, which throws an error in the test environment.

My Test File (test/myLib/myDir/combo.test.js); attempt to use Sinon package to mock

const sinon = require('sinon')

const dependencyModule = require('./external-function')// Defines the method dependencyModule.methodToMock

const myStub = sinon.stub(dependencyModule, 'methodToMock').returns(555) // Stubs dependencyModule.methodToMock and ensures it always returns the value: 555.

const comboObj = myCombo({}) // Instantiate object to expose method to test.

await comboObj.myMethod()// Call method that I want to test.  This throws type error because myMethod function calls externalFunction, which throws an error in the test environment.

How? You need to follow "stubbed module can not be destructured." on the official guide How to stub a dependency of a module

For example I have file external-function.js, combo.js and test.js on the same directory. I choose to use console.log to show that stub works and fake function get called, because you are not expecting something returned on myMethod .

// File: external-function.js
function externalFunction () {
  console.log('Original Called');
}

module.exports = { externalFunction };
// File: combo.js
// Note: "stubbed module can not be destructured."
const externalFunction = require('./external-function')
class Combo {
  constructor(props) {}
  async myMethod () {
    externalFunction.externalFunction()
  }
}
const myCombo = props => new Combo(props)
module.exports = { myCombo };
// File: test.js
const sinon = require('sinon');
const { myCombo } = require('./combo');
const dependencyModule = require('./external-function');

describe('myCombo', () => {
  it('myMethod', async () => {
    sinon.stub(dependencyModule, 'externalFunction').callsFake(() => {
      console.log('Fake Called');
    });

    const comboObj = myCombo({});

    await comboObj.myMethod();
  });
});

When I run it using nyc and mocha on my terminal:

$ npx nyc mocha test.js


  myCombo
Fake Called
    ✓ myMethod


  1 passing (3ms)

----------------------|---------|----------|---------|---------|-------------------
File                  | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------------------|---------|----------|---------|---------|-------------------
All files             |   85.71 |      100 |      75 |   83.33 |                   
 combo.js             |     100 |      100 |     100 |     100 |                   
 external-function.js |      50 |      100 |       0 |      50 | 2                 
----------------------|---------|----------|---------|---------|-------------------

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM