如何用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
相关产品推荐
相关产品推荐

