Codezilla
Codezilla

Reputation: 95

Jest: How to I test a function that calls another function in the body

I am trying to test the makeRandomComputerMove function, however, I am unable to properly mock the getRandomNumber function exported from the same module using Jest.

If I call the getRandomNumber function directly in the test file it works as expected, but I was under the impression that mocking the function in the test file should force the internal makeRandomComputerMove function to use the mocked value.

Any help would be appreciated.

test.ticTacToe.js

describe('TicTacToe Utils', () => {
    const randomMock = jest.spyOn(Utils, 'getRandomNumber')
        .mockReturnValueOnce(0)
        .mockReturnValueOnce(1)

    const board = [
        [['X'], [], []],
        [[], [], []],
        [[], [], []]
        ]

    it('makeRandomComputerMove', () => {
        const location = Utils.makeRandomComputerMove(board)
        // expect(location.x).toBe(0)
        // expect(location.y).toBe(1)
    })
})

ticTacToe.js

export const getRandomNumber = (min, max) => {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

export const makeRandomComputerMove = (board) => {
    const location = {};
    location.x = getRandomNumber(0, board.length - 1);
    location.y = getRandomNumber(0, board.length - 1);
    if (location.x < 3 && location.y < 3) {
        return location

    }
    return makeRandomComputerMove(board);   
};

Upvotes: 2

Views: 378

Answers (1)

Steve Holgado
Steve Holgado

Reputation: 12071

You won't be able to mock getRandomNumber while it's being called by makeRandomComputerMove within the same file.

Instead, you could move getRandomNumber to a separate file, which can then be mocked:

getRandomNumber.js

export const getRandomNumber = (min, max) => {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

ticTacToe.js

import { getRandomNumber } from './getRandomNumber';

export const makeRandomComputerMove = (board) => {
  const location = {};
  location.x = getRandomNumber(0, board.length - 1);
  location.y = getRandomNumber(0, board.length - 1);
  if (location.x < 3 && location.y < 3) {
    return location
  }
  return makeRandomComputerMove(board)
}

test.ticTacToe.js

import Utils from './'
import { getRandomNumber } from './getRandomNumber'

jest.mock('./getRandomNumber', () => ({
  getRandomNumber: jest.fn()
}))

describe('TicTacToe Utils', () => {
  getRandomNumber.mockReturnValueOnce(0)
  getRandomNumber.mockReturnValueOnce(1)

  const board = [
    [['X'], [], []],
    [[], [], []],
    [[], [], []]
    ]

  it('makeRandomComputerMove', () => {
    const location = Utils.makeRandomComputerMove(board)
    expect(location.x).toBe(0)
    expect(location.y).toBe(1)
  })
})

I hope this helps.

Upvotes: 1

Related Questions