You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Jest测试接收组件参数的React渲染属性?

测试接收组件作为参数的renderProp的正确方式

问题场景

现有包装组件:

function SomeRenderComponent({ render }) {
  return <> {render({ renderArgument: <SomeComponent /> })} </>;
}

编写的测试用例执行失败:

import { render } from "@testing-library/react";

test("provided a renderProp expect the renderProp to be called with component", () => {
  // arrange
  const renderProp = jest.fn();

  const expected = {
    renderArgument: <SomeComponent />,
  };

  // act
  render(<SomeRenderComponent render={renderProp} />);

  // assert
  expect(renderProp).toHaveBeenCalledWith(expected);
});

失败原因:直接比较React元素实例时,每次调用<SomeComponent />都会生成新的对象引用,导致全等匹配失败。


解决方案

方法1:用expect.any()匹配组件类型

直接检查传入参数中renderArgument的组件类型:

test("renderProp receives the correct component", () => {
  const renderProp = jest.fn();

  render(<SomeRenderComponent render={renderProp} />);

  expect(renderProp).toHaveBeenCalledWith(
    expect.objectContaining({
      renderArgument: expect.any(SomeComponent)
    })
  );
});

方法2:检查React元素核心标识

React元素包含$$typeof和type属性,可精准匹配这两个字段:

test("renderProp receives the correct component element", () => {
  const renderProp = jest.fn();

  render(<SomeRenderComponent render={renderProp} />);

  expect(renderProp).toHaveBeenCalledWith(
    expect.objectContaining({
      renderArgument: expect.objectContaining({
        type: SomeComponent,
        $$typeof: Symbol.for('react.element')
      })
    })
  );
});

方法3:自定义匹配器实现componentIs

如果需要复用类似expect.componentIs的逻辑,可自定义Jest匹配器:

// 在测试文件顶部或全局setup文件中定义
expect.extend({
  componentIs(received, expectedComponent) {
    const pass = received.type === expectedComponent;
    if (pass) {
      return {
        message: () => `expected ${received.type.name} not to be ${expectedComponent.name}`,
        pass: true
      };
    } else {
      return {
        message: () => `expected ${received.type?.name || 'unknown element'} to be ${expectedComponent.name}`,
        pass: false
      };
    }
  }
});

// 测试用例中使用
test("renderProp receives the correct component via custom matcher", () => {
  const renderProp = jest.fn();

  render(<SomeRenderComponent render={renderProp} />);

  expect(renderProp).toHaveBeenCalledWith(
    expect.objectContaining({
      renderArgument: expect.componentIs(SomeComponent)
    })
  );
});

方法4:验证组件渲染结果(贴近用户行为)

如果需要确保组件实际渲染内容正确,可结合React Testing Library的查询方法:

test("renderProp renders the correct component", () => {
  let renderedComponent;
  const renderProp = (props) => {
    renderedComponent = props.renderArgument;
    return null;
  };

  render(<SomeRenderComponent render={renderProp} />);
  // 单独渲染拿到的组件并验证内容
  render(renderedComponent);
  // 假设SomeComponent渲染了带有text="test"的元素
  expect(screen.getByText("test")).toBeInTheDocument();
});

内容的提问来源于stack exchange,提问作者josias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 13:30:05