我在尝试使用 Jest 将测试添加到我现有的 Create React App (CRA) 项目(该项目使用 Mantine v6 组件)时面临挑战。我一直遵循 Mantine 文档和其他在线资源中的测试指南,但仍然遇到一些问题。
项目详情: 框架:创建 React 应用程序 曼汀版本:v6.0.21 测试框架:Jest
问题描述: 我创建了一个自定义渲染函数,用 MantineProvider 包装我的组件以提供 Mantine 主题和上下文。但是,我遇到了一个反复出现的问题,即 MantineProvider 在日志中显示为 null 或未定义,导致我的测试失败。
我采取的步骤: 模拟主题:我尝试在测试文件中模拟主题对象,以在加载之前提供默认值。 useMantineTheme 和 waitFor:我在自定义渲染函数中使用了 useMantineTheme 挂钩,并将断言包装在 waitFor 中,以确保在测试运行之前加载主题。 检查循环依赖关系:我已确保不存在可能导致问题的循环依赖关系。
代码片段: 渲染.tsx:
import {
render as rtlRender,
RenderOptions,
waitFor,
} from "@testing-library/react";
import { MantineProvider, useMantineTheme } from "@mantine/core";
export const AllTheProviders = ({
children,
}: {
children: React.ReactNode;
}) => {
const comp = <MantineProvider>{children}</MantineProvider>;
return comp;
};
export const render = async (
ui: React.ReactNode,
options?: Omit<RenderOptions, "wrapper">,
) => {
const result = rtlRender(ui, {
wrapper: AllTheProviders,
...options,
});
return result;
};
Header.tsx :
import {
Burger,
Container,
Group,
Header,
Image,
MediaQuery,
Text,
useMantineTheme,
} from "@mantine/core";
import { Dispatch, SetStateAction } from "react";
import { Settings } from "../../../../Types";
import { useMediaQuery } from "@mantine/hooks";
export const HeaderComponent = ({
navBarOpened,
setNavBarOpened,
settings,
}: {
navBarOpened: boolean;
setNavBarOpened: Dispatch<SetStateAction<boolean>>;
settings: Settings;
}) => {
const theme = useMantineTheme();
const mobileScreen = useMediaQuery(`(max-width: ${theme.breakpoints.sm})`);
return (
<Header
height={80}
sx={(theme) => ({
display: "flex",
alignItems: "center",
paddingLeft: theme.spacing.md,
paddingRight: theme.spacing.md,
})}
>
<Group w="100%">
<MediaQuery largerThan="sm" styles={{ display: "none" }}>
<Burger
opened={navBarOpened}
onClick={() => setNavBarOpened((o) => !o)}
size="sm"
maw="0.5rem"
mr="xl"
/>
</MediaQuery>
<Image
width={mobileScreen ? "18em" : "24em"}
/>
{!mobileScreen && (
<Container pos="absolute" right="0rem">
<Text fz="xs" c="dimmed">
index: {settings.index}
</Text>
<Text fz="xs" c="dimmed">
model: {settings.name}
</Text>
<Text fz="xs" c="dimmed">
model id: {settings.modelId}
</Text>
</Container>
)}
</Group>
</Header>
);
};
标头.test.tsx:
import { HeaderComponent } from ".";
import { render, screen } from "../../../../test-utils";
import { Settings } from "../../../../Types";
const mockUseMediaQuery = jest.fn();
const mockUseMantineTheme = jest.fn();
jest.mock("@mantine/hooks", () => ({
useMediaQuery: () => mockUseMediaQuery(),
}));
jest.mock("@mantine/core", () => ({
useMantineTheme: () => mockUseMantineTheme(),
createStyles: () => () => ({}),
}));
jest.mock("@mantine/prism", () => ({
Prism: () => <div>Mocked Prism Component</div>,
}));
jest.mock("@mantine/dates", () => ({
Dates: () => <div>Mocked Date Component</div>,
}));
jest.mock("@emotion/react", () => ({
...jest.requireActual("@emotion/react"),
useTheme: () => ({}),
}));
describe("HeaderComponent", () => {
it("renders logo and settings on larger screens", () => {
mockUseMediaQuery.mockReturnValue(false);
const settings = new Settings({
index: "myIndex",
modelName: "myModel",
modelId: "myModelId",
});
render(
<HeaderComponent
navBarOpened={false}
setNavBarOpened={jest.fn()}
settings={settings}
/>,
);
expect(screen.getByRole("img")).toBeInTheDocument();
expect(screen.getByText(/index: myIndex/i)).toBeInTheDocument();
expect(screen.getByText(/model: myModel/i)).toBeInTheDocument();
expect(screen.getByText(/model id: myModelId/i)).toBeInTheDocument();
});
});
错误信息:
控制台错误 警告:React.jsx:类型无效 - 需要一个字符串(对于内置组件)或一个类/函数(对于复合组件),但得到:未定义。您可能忘记从定义它的文件中导出组件,或者您可能混淆了默认导入和命名导入。
Check the render method of `AllTheProviders`.
at AllTheProviders (/Users/soham/Desktop/sycamore/apps/demo-ui/ui/src/test-utils/render.tsx:11:11)
13 | children: React.ReactNode;
14 | }) => {
> 15 | const comp = <MantineProvider>{children}</MantineProvider>;
| ^
16 | return comp;
17 | };
18 | export const render = async (
throw new Error('元素类型无效:需要一个字符串(对于内置 ' + ' 组件)或类/函数(对于复合组件) ' + ("but got: " + (type == null ? type : typeof type) + ". + info));^
错误:元素类型无效:需要一个字符串(对于内置组件)或一个类/函数(对于复合组件),但得到:未定义。您可能忘记从定义它的文件中导出组件,或者您可能混淆了默认导入和命名导入。
检查AllTheProviders的render方法。
Здравствуйте вы исправили ошибку ? у меня тоже похоже проблемы