4
votes

I'm struggling with using spyOn as part of testing my utils.js module. I've tried various methods and approaches but all seem to yield the "expected mock function to have been called". For the record, other unit tests work OK, so there shouldn't be any issue with my actual test setup.

Below is a simplified test case with two functions and one test, and I can't even get these to work. Did I misunderstand the spyOn altogether?

// utils.js
function capitalHelper(string){
  return string.toUpperCase();
}

function getCapitalName(inputString){
  return capitalHelper(inputString.charAt(0)) + inputString.slice(1);
}

exports.capitalHelper = capitalHelper
exports.getCapitalName = getCapitalName



// utils.test.js
const Utils = require('./utils');

test('helper function was called', () => {
  const capitalHelperSpy = jest.spyOn(Utils, 'capitalHelper');
  const newString = Utils.getCapitalName('john');
  expect(Utils.capitalHelper).toHaveBeenCalled();
})
1
Btw, I did look at similar posts, but found none that really explained why this doesn't work for me.terjeofnorway
You should be able to assert the toHaveBeenCalled() against capitalHelperSpy instead of directly against the object method. See the example here: facebook.github.io/jest/docs/en/…Steve Vaughan
Yep, I did that as well, with the same result...terjeofnorway

1 Answers

3
votes

I do ont use spyOn(), but jest.fn() instead for all mock scenario

In your case I would do the following

test('helper function was called', () => {
    Utils.capitalHelper = jest.fn((s) => Utils.capitalHelper(s))
    const newString = Utils.getCapitalName('john')
    expect(Utils.capitalHelper.mock.calls.length).toBe(1)
})

First line could have simply be :

Utils.capitalHelper = jest.fn()

since you don't seem to be testing the returned value in your test :)

You can find more details on jest.fn() on the jest official documentation : https://facebook.github.io/jest/docs/en/mock-functions.html

----------------------- EDIT

I got it : the problem occurs because within your utils.js file, getCapitalName uses the defined function, not the one pointed by the export.

To be able to mock the function in use you could change your utils.js file to

// utils.js
const Utils = {
    capitalHelper: string => string.toUpperCase(),
    getCapitalName: inputString => Utils.capitalHelper(inputString.charAt(0)) + inputString.slice(1)
}

export default Utils

then the tests I gave before will work