错误:在现有 CRA 应用程序中使用 Jest 测试 Mantine v6 组件

问题描述 投票:0回答:1

我在尝试使用 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方法。

typescript create-react-app ts-jest mantine
1个回答
-1
投票

Здравствуйте вы исправили ошибку ? у меня тоже похоже проблемы

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.