DaveDavidson
DaveDavidson

Reputation: 206

Sinon Spy to check function has been called

I am trying to use sinon.spy() to check that a function has been called. The function is called getMarketLabel and it returns marketLabel and accepts it into the function. I need to check that getMarketLabel has been called. I actually call getMarketLabel in one place, like so: {getMarketLabel(sel.get('market'))} The code I have so far is:

describe('Check if it has been called', () => {
  let spy;
  beforeEach(() => {
    spy = sinon.spy(getMarketLabel, 'marketLabel');
  })
  it('should have been called', () => {
    expect(spy).to.be.calledWith('marketLabel');
  });
});

This is the error I receive: TypeError: Attempted to wrap undefined property marketLabel as function

Upvotes: 1

Views: 4709

Answers (2)

rabbitco
rabbitco

Reputation: 2850

This is the error I receive: TypeError: Attempted to wrap undefined property marketLabel as function

You need to require the helper.js into your test file, then replace the relevant method on the required module and finally call the method replaced with the spy:

var myModule = require('helpers'); // make sure to specify the right path to the file

describe('HistorySelection component', () => {
  let spy;
  beforeEach(() => {
    spy = sinon.stub(myModule, 'getMarketLabel'); // replaces method on myModule with spy
  })
  it('blah', () => {
    myModule.getMarketLabel('input');
    expect(spy).to.be.calledWith('input');
  });
});

You cannot test whether the spy is called with helpers.sel('marketLabel') as this function will be executed before the test is conducted. You will therefore by writing:

expect(spy).to.be.calledWith(helpers.sel('marketLabel'));

be testing that that the spy is called with whatever value returned by helpers.sel('marketLabel') (which is undefined by default).


The content of helper.js should be:

module.exports = {
  getMarketLabel: function (marketLabel) {
    return marketLabel
  }
}

Upvotes: 0

robertklep
robertklep

Reputation: 203304

Sinon can't spy on functions that aren't a property of some object, because Sinon has to be able to replace the original function getMarketLabel by a spied-on version of that function.

A working example:

let obj = {
  getMarketLabel(label) {
    ...
  }
}
sinon.spy(obj, 'getMarketLabel');

// This would call the spy:
obj.getMarketLabel(...);

This syntax (which is close to what you're using) also exists:

let spy = sinon.spy(getMarketLabel);

However, this only triggers the spy code when explicitly calling spy(); when you call getMarketLabel() directly, the spy code isn't called at all.

Also, this won't work either:

let getMarketLabel = (...) => { ... }
let obj            = { getMarketLabel }
sinon.spy(obj, 'getMarketLabel');

getMarketLabel(...);

Because you're still calling getMarketLabel directly.

Upvotes: 2

Related Questions