【问题标题】:How to mock a react function component that takes a ref prop?如何模拟采用 ref 道具的反应函数组件?
【发布时间】:2022-10-19 22:27:58
【问题描述】:

问题:

我正在尝试使用 jest 和 React 测试库来模拟包装在 React.ForwardRef() 中的功能组件,但我不断收到此警告(我的测试失败):

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

这是我要测试的组件:

const ParentComponent = () => {
  const childRef = useRef(null);

  return (
    <div data-testid="parent">
      Parent
      {/* want to mock this ChildComponent */}
      <ChildComponent ref={childRef} />
    </div>
  );
};

这是我要模拟的组件:

const ChildComponent = forwardRef((props, ref) => (
  <div ref={ref} {...props}>
    Child
  </div>
));

我试过的:


jest.mock("../ChildComponent", () => ({
  __esModule: true,
  default: () => <div>Mock Child</div>
}));

结果Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?


jest.mock('../ChildComponent', () => {
  const { forwardRef } = jest.requireActual('react');
  return {
    __esModule: true,
    default: () => forwardRef((props, ref) => <div ref={ref} />),
  };
});

结果Objects are not valid as a React child (found: object with keys {$$typeof, render})

【问题讨论】:

    标签: reactjs jestjs react-testing-library


    【解决方案1】:

    亲爱的,我刚刚遇到了同样的问题,你最后一次尝试在模拟函数中导入 forwardRef 帮助我解决了这个问题。我很幸运:

    jest.mock('../../../client/components/visualizations/Visualizer', () => {
      const { forwardRef } = jest.requireActual('react');
      return {
        __esModule: true,
        default: forwardRef(() => <div></div>),
      };
    });
    

    因此,使用上面的示例,我相信这应该可行:

    jest.mock('../ChildComponent', () => {
      const { forwardRef } = jest.requireActual('react');
      return {
        __esModule: true,
    -   default: () => forwardRef((props, ref) => <div ref={ref} />),
    +   default: forwardRef((props, ref) => <div ref={ref} />),
      };
    });
    

    还包括我自己在下面的尝试以及生成的错误消息,以防它帮助其他人将来找到这篇文章:

    jest.mock('../ChildComponent', () => ({
      __esModule: true,
      default: React.forwardRef(() => <div></div>),
    }));
    

    导致错误:

    The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.
        Invalid variable access: React`
    

    【讨论】:

    • 这解决了我的(略有不同的)问题!我将用我的“版本”发布答案。
    【解决方案2】:

    我遇到了与 Ryan S 类似的问题,并使用了 their answer 并稍作修改。

    在我的问题中,我必须使用酶测试是否呈现了确切的子组件,但不使用酶的mountshallow

    it('renders the child', () => {
      expect(wrapper.exists(ChildComponent)).toBe(true);
    })
    

    因此,我对解决方案的修改是:

    jest.mock('../ChildComponent', () => {
      const { forwardRef } = jest.requireActual('react');
      const ChildComponentShim = jest.requireActual('../ChildComponent');
      return {
        __esModule: true,
        default: forwardRef((props, ref) => <ChildComponentShim { ...props } ref={ref} />),
      };
    });
    

    这仅仅是让实际的要渲染的子组件,但确保使用来自 forwardRef 的 ref 而不安装父组件或子组件。

    【讨论】:

      猜你喜欢
      • 2018-02-13
      • 2015-08-28
      • 2021-10-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-25
      • 1970-01-01
      • 2020-11-10
      • 2017-01-12
      相关资源
      最近更新 更多