Skip to content
Advertisement

How to set a Sinon spy for a dependency defined in a class, rather than a Sinon stub?

I am unit testing a method defined in a module, which itself calls a dependency defined in a second module. I want to set a spy for the method-under-test’s call to the dependency, using the Sinon package. How do I do that? I’ve seen Sinon’s page on mocking the dependency of a module (see here), and have been able to use it successfully in the past. But in this case, my test code (see below) is still calling the original method, not the spy.

FYI in my code, if I assign a Sinon stub to the method, instead of Sinon spy, then the stubbed method is indeed called, as expected. I’m not sure why I can stub, but not spy in this case.

In this case, using stub is fine for my purposes. But I’m curious as to why I cannot use spy here as I’ve done in the past.

Thanks.


My Code

combo-test.js (test file)

  const { tape } = require('tape')
  const sinon = require('sinon')
  const { myCombo } = require('./lib/ow/combo')
  const { ComboDropdown } = require('../../../lib/ow/combo-dropdown')

  const comboObject = myCombo(props)// Instantiate object to expose method-under-test.

  sinon.spy(ComboDropdown.prototype, 'extMethod')// Mock call to external method with a spy.
  // sinon.stub(ComboDropdown.prototype, 'extMethod')

  comboObj.myMethod()// Prints to console:  555

combo.js (defines method-under-test)

const { ComboDropdown } = require('./combo-dropdown')

class Combo extends myClass {
  constructor(props) {
  }
  myMethod() {// method-under-test
    this.dropdown = new ComboDropdown({
    })
    this.dropdown.extMethod()//Calls external method.
  }
}
const myCombo = props => new Combo(props)
module.exports = { myCombo }

combo-dropdown.js (defines external method)

class ComboDropdown extends Dropdown {
  constructor(props) {
    super(props)
  }
  extMethod() {
    console.log(555)
  }
}
module.exports = {
  ComboDropdown
}

Advertisement

Answer

sinon.spy(object, "method") creates a spy that wraps the existing function object.method. The spy will behave exactly like the original method (including when used as a constructor), but you will have access to data about all calls.

sinon.spy() just add the calls information to the target method without changing its behavior or implementation, leaving it with its original implementation. With the calls information, you can make assertions after executing the code under test, such as whether the method was called or not.

If you want to have both the calls information and also change the implementation of the target method. sinon.stub(object, 'method') is the correct way. It will replace object.method with a stub function.

Besides, you can use such stub.returns(obj); API to make the stub return the provided value.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement