如何在每个测试中更改 jest 模拟函数的返回值?

IT技术 reactjs react-native jestjs enzyme
2021-03-27 23:02:15

我的组件测试文件中有一个这样的模拟module

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

这些函数将在我的组件的渲染函数中调用以隐藏和显示某些特定功能。

我想对这些模拟函数的返回值的不同组合进行快照。

因为假设我有一个这样的测试用例

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

我想要改变模拟module函数的返回值来运行这个测试案例false是这样动态

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

因为我已经导入RowListItem了一次组件,所以我的模拟module不会再次导入。所以它不会改变。我该如何解决这个问题?

3个回答

您可以模拟该module,使其返回间谍并将其导入您的测试:

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

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

然后稍后您可以使用更改实际实现 mockImplementation

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

并在接下来的测试中

navigationEnabled.mockImplementation(()=> false)
//or
navigationEnabled.mockReturnValueOnce(false);
相关引用:“但通常你需要在module使用之前指示 Jest 使用模拟。因此,Jest 会自动将 jest.mock 调用提升到module的顶部(在任何导入之前)。” 来自:jestjs.io/docs/en/manual-mocks
2021-05-23 23:02:15
也许当时情况并非如此,但jest.mock需要在进行导入之前调用。
2021-06-01 23:02:15
@Sylvain 在 ES6 导入之前不能/不会调用任何东西,它们被静态强制为第一个。
2021-06-11 23:02:15
@OlaoyeOluwapelumi 你可以在你想要的任何东西之前输入它,但它不会在 ES6 导入之后执行,因为它们被静态强制为首先被处理。
2021-06-16 23:02:15
这是一个深入概述此技术的教程 - mikeborozdin.com/post/changed-jest-mocks-between-tests
2021-06-17 23:02:15

你想做的是

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);
  });
});

您可以在此处查看有关这些功能的更多信息 => https://facebook.github.io/jest/docs/mock-functions.html#mock-return-values

对于 TS 你需要做的 (mockedFn as jest.Mock). mockReturnValueOnce
2021-05-25 23:02:15
如果使用ts-jest,则mocked(mockedFn)包装器是同一事物的语法糖。github.com/kulshekhar/ts-jest/blob/master/docs/user/...
2021-06-13 23:02:15
这不适用于typescript,您将得到:属性 'mockReturnValueOnce' 在类型 '() => string' 上不存在。
2021-06-16 23:02:15

我很难得到公认的答案来工作——当我试图调用它们时,我的等价物navigationEnabledguidanceEnabled是未定义的mockReturnValueOnce

这是我必须做的:

../../../magic/__mocks__/index.js

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

在我的index.test.js文件中:

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);
});