React/TypeScript组件Jest测试报错:Element type is invalid
解决React/TypeScript Jest测试中「Element type is invalid」错误
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
你遇到的问题并非DefaultTitleRenderer的导入导出错误,而是测试中mock模块时遗漏了必要的组件/导出项,导致渲染时用到了undefined的元素,具体有两个核心原因:
1. @test/frameworks-react-apollo的mock覆盖了ApolloProvider
你用jest.mock替换了该模块,但仅返回了useQuery,而测试代码里需要用到该模块的ApolloProvider组件。被mock后的模块中不存在ApolloProvider,它会变为undefined,渲染<ApolloProvider>时就触发了错误。
2. 未mock@test/components-fluent-ui模块
DefaultTitleRenderer组件依赖了该模块的StyledText、Button、Tooltip组件,但测试中未对这个模块做mock处理。Jest在测试环境下无法解析这些第三方UI组件,导致它们变为undefined,渲染时引发错误。
修复后的测试代码
import * as React from "react"; import { render } from "@testing-library/react"; import { DefaultTitleRenderer } from "./default-title-renderer"; import { ApolloProvider } from "@test/frameworks-react-apollo"; import { createApolloClientMock } from "@test/utilities-test-apollo"; const mockClient = createApolloClientMock(); // 保留原有mock,补充返回ApolloProvider并给useQuery模拟数据 jest.mock("@test/frameworks-react-apollo", () => ({ useQuery: jest.fn().mockReturnValue({ data: "测试标题" }), ApolloProvider: ({ children }: { children: React.ReactNode }) => <div>{children}</div>, })); // mock @test/components-fluent-ui的所有导出组件 jest.mock("@test/components-fluent-ui", () => ({ StyledText: ({ children }: { children: React.ReactNode }) => <span data-testid="styled-text">{children}</span>, Button: ({ children }: { children: React.ReactNode }) => <button>{children}</button>, Tooltip: ({ children }: { children: React.ReactNode }) => <div>{children}</div>, })); // 模拟组件中用到的ArrowStartIcon(根据实际导入路径调整) jest.mock("@test/icons", () => ({ ArrowStartIcon: () => <span>←</span>, })); jest.mock("@test/components-1", () => ({ use1Context: jest.fn(), })); describe("DefaultTitleRenderer", () => { it("renders the header title", () => { const { getByTestId } = render( <ApolloProvider client={mockClient}> <DefaultTitleRenderer /> </ApolloProvider> ); const pageHeader = getByTestId("example"); expect(pageHeader).toBeInTheDocument(); }); });
额外说明:
- 给
useQuery模拟返回data值,避免组件中{data}渲染时出现异常 - 所有组件依赖的第三方UI组件都需要在测试中做简单mock,确保它们是有效的React元素
- 如果
handleBackNavigation、styles()、someStyles()这些函数来自外部依赖或需要模拟,也要补充对应的mock逻辑
内容的提问来源于stack exchange,提问作者HackerMan33453
相关产品推荐
相关产品推荐

