What is the proper way to change the `jest mock return value` in each test case?

What is the proper way to change the jest mock return value in each test case, especially when dealing with a mock module that is already imported in my component test file?

Here is an example of how I have set up my mock:

jest.mock('../../../magic/index', () => ({
navigationEnabled: () => true,
guidanceEnabled: () => true
}));

These mock functions are called inside the render function of my component to show or hide certain features.

Now, I want to take snapshots for different combinations of the return values of these mock functions. For example, I have the following test case:

it('RowListItem should not render navigation and guidance options', () => {
const wrapper = shallow(
<RowListItem type="regularList" {...props} />
);
expect(enzymeToJson(wrapper)).toMatchSnapshot();
});

To run this test, I want to change the mock functions’ return values to false dynamically, like this:

jest.mock('../../../magic/index', () => ({
navigationEnabled: () => false,
guidanceEnabled: () => false
}));

The issue is that since I am importing the RowListItem component, the mock module doesn’t get re-imported, so the mock return values don’t change as expected.

What is the solution to update the mock return values dynamically for each test case in this scenario?

Hi,

You can solve this issue by mocking the module so it returns spies and then importing it into your test. Here’s how you can achieve that:

import { navigationEnabled, guidanceEnabled } from '../../../magic/index';

jest.mock('../../../magic/index', () => ({
navigationEnabled: jest.fn(),
guidanceEnabled: jest.fn()
}));

Now, you can use jest mock return value methods like mockImplementation or mockReturnValueOnce to change the return values dynamically in each test case.

For example:

navigationEnabled.mockImplementation(() => true); // Sets the return value to true for all subsequent calls

or

navigationEnabled.mockReturnValueOnce(true); // Sets the return value to true only for the next call

Then in the next test

navigationEnabled.mockImplementation(() => false); // Changes the return value to false for all subsequent calls

or

navigationEnabled.mockReturnValueOnce(false); // Sets the return value to false only for the next call

You can also use beforeEach to set the mock return values at the start of each test case:

beforeEach(() => {
navigationEnabled.mockReturnValue(false);
guidanceEnabled.mockReturnValue(true);
});