【问题标题】:how to change jest mock function return value in each test?如何在每次测试中更改 jest mock 函数返回值?
【发布时间】:2018-01-27 05:47:54
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: reactjs react-native jestjs enzyme


    【解决方案1】:

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

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

    【讨论】:

    • 可能当时不是这样,但是在导入之前需要调用jest.mock
    • @Sylvain 在 ES6 导入之前不能/不会调用任何东西,它们被静态强制为第一个。
    • @OlaoyeOluwapelumi 你可以在任何你想要的之前输入它,但它不会在 ES6 导入之后被执行,因为它们被静态强制被视为第一个。
    • 相关引用:“但通常你需要在模块使用之前指示 Jest 使用模拟。因此,Jest 会自动将 jest.mock 调用提升到模块顶部(在任何导入之前) )。”来自:jestjs.io/docs/en/manual-mocks
    • 这里有一个深入介绍这种技术的教程 - mikeborozdin.com/post/changing-jest-mocks-between-tests
    【解决方案2】:

    你想做的是

    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

    【讨论】:

    • 这不适用于 typescript,你会得到:Property 'mockReturnValueOnce' does not exist on type '() => string'。
    • 对于TS你需要做(mockedFn as jest.Mock). mockReturnValueOnce
    • 如果使用ts-jestmocked(mockedFn) 包装器是同一事物的语法糖。 github.com/kulshekhar/ts-jest/blob/master/docs/user/…
    【解决方案3】:

    我很难得到公认的答案——当我尝试调用 mockReturnValueOnce 时,我的 navigationEnabledguidanceEnabled 等价物是未定义的。

    这是我必须做的:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-29
      • 2021-02-20
      • 2018-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-18
      相关资源
      最近更新 更多