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

pas*_*lus 33 reactjs jestjs react-native enzyme

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

  jest.mock('../../../magic/index', () => ({
    navigationEnabled: () => true,
    guidanceEnabled: () => true
  }));
Run Code Online (Sandbox Code Playgroud)

这些函数将在我的组件的render函数中调用,以隐藏和显示一些特定的功能.

我想对这些模拟函数的返回值的不同组合拍摄快照.

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

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

运行这个测试用例我想将模块模块函数的返回值false动态更改为这样

jest.mock('../../../magic/index', () => ({
    navigationEnabled: () => false,
    guidanceEnabled: () => false
  }));
Run Code Online (Sandbox Code Playgroud)

因为我已经导入RowListItem组件一次所以我的模拟模块不会再次导入.所以它不会改变.我怎么能解决这个问题?

And*_*rle 53

您可以模拟模块,以便它返回间谍并将其导入您的测试:

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

jest.mock('../../../magic/index', () => ({
    navigationEnabled: jest.fn(),
    guidanceEnabled: jest.fn()
}));
Run Code Online (Sandbox Code Playgroud)

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

navigationEnabled.mockImplementation(()=> true)
//or
navigationEnabled.mockReturnValueOnce(true);
Run Code Online (Sandbox Code Playgroud)

并在下一次测试中

navigationEnabled.mockImplementation(()=> false)
//or
navigationEnabled.mockReturnValueOnce(false);
Run Code Online (Sandbox Code Playgroud)

  • 相关引用:“但通常您需要在模块使用模拟之前指示 Jest 使用模拟。因此,Jest 会自动将 jest.mock 调用提升到模块的顶部(在任何导入之前)。” 来自:https://jestjs.io/docs/en/manual-mocks (7认同)
  • @OlaoyeOluwapelumi 你可以在你想要的之前输入它,但是直到 ES6 导入之后它才会被执行,因为它们被静态地强制被视为第一个。 (3认同)
  • 这是一个深入概述此技术的教程 - https://mikeborozdin.com/post/changing-jest-mocks- Between-tests/ (3认同)
  • 也许当时情况并非如此,但在导入之前需要调用`jest.mock`。 (2认同)
  • @Sylvain 在 ES6 导入之前什么都不能/不会被调用,它们被静态地强制为第一个。 (2认同)

Day*_*eon 8

你想做的是

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);
  });
});
Run Code Online (Sandbox Code Playgroud)

你可以在这里查看更多关于这些函数的信息=> https://facebook.github.io/jest/docs/mock-functions.html#mock-return-values

  • 对于 TS,你需要执行 `(mockedFn as jest.Mock)。模拟返回值一次` (13认同)
  • 这不适用于打字稿,您将得到:属性“mockReturnValueOnce”在类型“() =&gt; string”上不存在。 (7认同)
  • 如果使用“ts-jest”,则“mocked(mockedFn)”包装器是同一事物的语法糖。https://github.com/kulshekhar/ts-jest/blob/master/docs/user/test-helpers.md#mocked (7认同)

Cas*_*ass 8

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

这是我必须做的:

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

export const navigationEnabled = jest.fn();
export const guidanceEnabled = jest.fn();
Run Code Online (Sandbox Code Playgroud)

在我的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);
});
Run Code Online (Sandbox Code Playgroud)