【问题标题】:How to hoist a jest dependency mock over actual dependency?如何在实际依赖项上提升一个笑话依赖项模拟?
【发布时间】:2019-08-08 20:54:34
【问题描述】:

我正在测试一个导入类 LanguageStore 的 react-native 组件。目前测试失败,因为组件正在实例化这个类,该类调用了一个在测试范围内未定义的私有设置器:

FAIL  src\modules\languageProvider\__tests__\LanguageProvider-test.js
  ● renders correctly

    TypeError: _this.strings.setLanguage is not a function

      at LanguageStore.setLanguage (src\modules\languageProvider\LanguageStore.js:25:15)
      at new LanguageProvider (src\modules\languageProvider\LanguageProvider.js:30:16)

问题:

如何在实际依赖中提升一个玩笑的依赖模拟?

为了解决这个问题,我根据这个答案How can I mock an ES6 module import using Jest? 调用了jest.mock。但是我得到了和以前一样的错误,因为测试调用的是 LanguageStore 的实现,而不是我在下面创建的模拟 - _this.strings.setLanguage is not a function

import { View } from 'react-native';
import React from 'react';
import { shallow } from 'enzyme';
import renderer from 'react-test-renderer';
import connect from '../connect.js';
import LanguageProvider from '../LanguageProvider';
import LanguageStore from '../LanguageStore';

it('renders correctly', () => {

  const TestComponent = connect(Test);
  const strings = { test: 'Test' };
  const language = "en"

  const stringsMock = {
    setLanguage: jest.fn()
  };

  const mockSetLanguage = jest.fn();
  jest.mock('../LanguageStore', () => () => ({
    language: language,
    strings: stringsMock,
    setLanguage: mockSetLanguage,
  }));

  const wrapper = shallow(<LanguageProvider strings={strings} language="en"><Test /></LanguageProvider>);

  expect(wrapper.get(0)).toMatchSnapshot();

});


class Test extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return <View />;
  }
}

这是一个链接到测试和相关的被测组件和类:

https://github.com/BrianJVarley/react-native-prototyping/blob/i18nProvider-feature/src/modules/languageProvider/tests/LanguageProvider-test.js

【问题讨论】:

    标签: react-native mocking jestjs es6-class


    【解决方案1】:

    Calling jest.mock within a test doesn't work.

    您需要将模拟移出测试并确保您的工厂函数没有任何外部依赖项。

    类似这样的:

    import { View } from 'react-native';
    import React from 'react';
    import { shallow } from 'enzyme';
    import connect from '../connect.js';
    import LanguageProvider from '../LanguageProvider';
    import LanguageStore from '../LanguageStore';
    
    jest.mock('../LanguageStore', () => {
      const language = "en"
      const stringsMock = {
        setLanguage: jest.fn()
      };
      const mockSetLanguage = jest.fn();
    
      return () => ({
        language,
        strings: stringsMock,
        setLanguage: mockSetLanguage,
      })
    });
    
    it('renders correctly', () => {
      const TestComponent = connect(Test);
      const strings = { test: 'Test' };
      const wrapper = shallow(<LanguageProvider strings={strings} language="en"><Test /></LanguageProvider>);
      expect(wrapper.get(0)).toMatchSnapshot();
    });
    
    
    class Test extends React.Component {
      constructor(props) {
        super(props);
      }
      render() {
        return <View />;
      }
    }
    

    【讨论】:

    • 好的,将模拟移到测试之外修复了提升问题 +1。所以本质上jest.mock 也必须返回模拟实现?我看到我也没有返回模拟。
    • @BrianJ 如果您使用工厂函数(jest.mock 的可选第二个参数),那么工厂函数必须返回模拟。 (实际上您正在返回模拟,因为没有包装{ }arrow function 自动返回其表达式主体的结果)
    • ok 解释了原因,之前我一直提供 () 而不是工厂函数
    猜你喜欢
    • 1970-01-01
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多