JS Jest: getting undefined error on simple mock test

Viewed 303

I have a simple function that takes a player and calls a nested function setPlayer() on it:

myFunction = (player) => {
    player.getData().setPlayer(true)
}

main.test.js

it('expects setPlayer to be called', () => {

    player = jest.fn();

    // mocking the myFunction 

    player.getData = jest.fn(() => {
      return {
        setPlayer: jest.fn().mockReturnValue(true),
      }
    })

    myFunction(player) // calling function

    expects(player.getData.setPlayer).toBeCalled();
});

I keep getting this error in my test though but I don't understand why. I seem to have everything mocked unless I am forgetting something:

expect(received).toBeCalled()

Matcher error: received value must be a mock or spy function

Received has value: undefined
1 Answers

I keep getting this error in my test though but I don't understand why.

player.getData is a mock function. That function doesn't have a setPlayer property. You are passing undefined to expects, hence the error.

Calling player.getData would return you an object with a setPlayer function, but you can't just do expects(player.getData().setPlayer) because that would return a different setPlayer mock function than the one called by myFunction.

Instead you simply create the setPlayer mock function up front and reference it directly. I also cleaned up the code a little.

it('expects setPlayer to be called', () => {

    const setPlayerMock = jest.fn().mockReturnValue(true);
    const player = {
      getData: jest.fn(() => {
        return {
          setPlayer: setPlayerMock,
        };
      }),
    };

    myFunction(player); // calling function

    expects(setPlayerMock).toBeCalled();
});

FWIW, with the information you have given, it wouldn't be necessary to use a mock function for getData, you could just do

const player = {
  getData() {
    return {setPlayer: setPlayerMock};
  },
}

You only need to use mock functions when you want to make assertions on them.

Related