how to change jest mock function return value in each test?

133,253

Solution 1

You can mock the module so it returns spies and import it into your test:

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

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

Then later on you can change the actual implementation using mockImplementation

navigationEnabled.mockImplementation(()=> true)
//or
navigationEnabled.mockReturnValueOnce(true);

and in the next test

navigationEnabled.mockImplementation(()=> false)
//or
navigationEnabled.mockReturnValueOnce(false);

Solution 2

what you want to do is

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

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

describe('test suite', () => {
  it('every test', () => {
    navigationEnabled.mockReturnValueOnce(value);
    guidanceEnabled.mockReturnValueOnce(value);
  });
});

you can look more about these functions here =>https://facebook.github.io/jest/docs/mock-functions.html#mock-return-values

Solution 3

I had a hard time getting the accepted answers to work - my equivalents of navigationEnabled and guidanceEnabled were undefined when I tried to call mockReturnValueOnce on them.

Here's what I had to do:

In ../../../magic/__mocks__/index.js:

export const navigationEnabled = jest.fn();
export const guidanceEnabled = jest.fn();

in my index.test.js file:

jest.mock('../../../magic/index');
import { navigationEnabled, guidanceEnabled } from '../../../magic/index';
import { functionThatReturnsValueOfNavigationEnabled } from 'moduleToTest';

it('is able to mock', () => {
  navigationEnabled.mockReturnValueOnce(true);
  guidanceEnabled.mockReturnValueOnce(true);
  expect(functionThatReturnsValueOfNavigationEnabled()).toBe(true);
});
Share:
133,253

Related videos on Youtube

pashaplus
Author by

pashaplus

Updated on October 16, 2020

Comments

  • pashaplus
    pashaplus over 3 years

    I have a mock module like this in my component test file

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

    these functions will be called in render function of my component to hide and show some specific feature.

    I want to take a snapshot on different combinations of the return value of those mock functions.

    for suppose I have a test case like this

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

    to run this test case I want to change the mock module functions return values to false like this dynamically

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

    because i am importing RowListItem component already once so my mock module wont re import again. so it wont change. how can i solve this ?

  • Sylvain B
    Sylvain B over 4 years
    Maybe it was not the case at the time, but jest.mock needs to be called before doing the import.
  • tommybernaciak
    tommybernaciak over 4 years
    this does not work with typescript, you will get: Property 'mockReturnValueOnce' does not exist on type '() => string'.
  • Dayan Moreno Leon
    Dayan Moreno Leon over 4 years
    for TS you need to do (mockedFn as jest.Mock). mockReturnValueOnce
  • oskarth
    oskarth over 4 years
    @Sylvain Nothing can/will be called before ES6 imports, they're statically enforced to being first.
  • Brent Sharrow
    Brent Sharrow about 4 years
    If using ts-jest, the mocked(mockedFn) wrapper is syntactical sugar for the same thing. github.com/kulshekhar/ts-jest/blob/master/docs/user/…
  • oskarth
    oskarth almost 4 years
    @OlaoyeOluwapelumi You can type it before all you want, but it won't get executed until after the ES6 imports, because they're statically enforced to being treated as first.
  • Pierre Henry
    Pierre Henry over 3 years
    Relevant citation: "But often you need to instruct Jest to use a mock before modules use it. For this reason, Jest will automatically hoist jest.mock calls to the top of the module (before any imports)." From: jestjs.io/docs/en/manual-mocks
  • Mike Borozdin
    Mike Borozdin about 3 years
    Here's a tutorial that outlines this technique in depth - mikeborozdin.com/post/changing-jest-mocks-between-tests
  • 高欣平
    高欣平 almost 2 years
    really helpful to typescript developers, thank you!!