【问题标题】:Unit testing Chakra UI with Jest使用 Jest 对 Chakra UI 进行单元测试
【发布时间】:2020-12-30 11:33:08
【问题描述】:

目前我正在尝试对我的应用程序进行单元测试,该应用程序是使用带有 typescript 的 Create-React-App 构建的,并且它的样式是 chakraui。 Chakrui 包含一个组件 ThemeProvider,它必须像这样包装整个应用程序。

这是我的 index.tsx 文件

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import { ThemeProvider, CSSReset } from "@chakra-ui/core/dist";
import { theme } from "@chakra-ui/core/dist";

ReactDOM.render(
  <React.StrictMode>
    <ThemeProvider theme={theme}>
      <CSSReset />
      <App />
    </ThemeProvider>
  </React.StrictMode>,
  document.getElementById("root")

对于我编写的每个单元测试,我都必须使用 ThemeProvider 包装组件以使测试通过:

import React from "react";
import { render } from "@testing-library/react";
import { ThemeProvider } from "@chakra-ui/core/dist";

import App from "./App";

describe("<App />", () => {
  test("smoke test", () => {
    render(
      <ThemeProvider>
        <App />
      </ThemeProvider>
    );
  });
});

但这非常冗长,并且必须为我编写的每个测试完成。有没有办法在每个.test.tsx 文件中只执行一次?

【问题讨论】:

    标签: reactjs jestjs react-testing-library


    【解决方案1】:

    您可以创建自己的主题包装函数

    import React from "react";
    import { ThemeProvider } from "@chakra-ui/core/dist";
    
    export const ThemeWrapper = ({ children }) => (
      <ThemeProvider>{children}</ThemeProvider>
    );
    

    然后在测试中指定包装器

    import React from "react";
    import { render } from "@testing-library/react";
    import { ThemeWrapper } from "../testUtils";
    
    import App from "./App";
    
    describe("<App />", () => {
      test("smoke test", () => {
        render(<App />, { wrapper: ThemeWrapper });
      });
    });
    

    这略微减少了测试代码。您也许还可以走创建自定义渲染函数的路线(按照redux 的步骤)。

    它可能看起来像

    import React from "react";
    import { render } from "@testing-library/react";
    import { ThemeProvider } from "@chakra-ui/core/dist";
    
    export const renderWithTheme = ui => {
      const Wrapper = ({ children }) => (
        <ThemeProvider>{children}</ThemeProvider>
      );
    
      return render(ui, { wrapper: Wrapper });
    };
    

    与上面的包装器基本相同,但更多地集成到测试渲染函数中。如果您需要传入主题对象或其他渲染选项,您也可以稍微调整函数签名,这只是一个简单的示例。

    现在测试看起来像

    import React from "react";
    import { renderWithTheme } from "../testUtils";
    
    import App from "./App";
    
    describe("<App />", () => {
      test("smoke test", () => {
        renderWithTheme(<App />);
    });
    

    【讨论】:

    • 哇!这很棒。 renderWithTheme 中的 ui 属性是干什么用的?
    • @RedSkyHarbor 这不是道具,它是正在渲染/测试的组件,只是遵循他们的测试文档中的 redux 命名约定。
    【解决方案2】:

    Jest 可能会从@chakra-ui/core/dist(取决于您的jest configuration模拟您的导入,这可能会导致您导入的 chakra-ui 组件未定义.

    导入 Theme Provider每次都将其包装 与您的渲染可能是一种方法。当您的index.tsx 中有多个组件 时,可能会出现问题。因此,您可能不想导入每个组件。

    在这种情况下,您需要从 @chakra-ui/core 导入 实际 组件。

    在 Jest 中最好的方法(根据我)是:

    jest.mock("@chakra-ui/core", () => {
        const ui = jest.requireActual("@chakra-ui/core");
        return {
            ...ui,
            customKey: 'customValue',
        };
    })
    

    这样您甚至可以将自定义函数和键值添加到导入的模块中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-12
      • 2020-12-28
      • 1970-01-01
      • 2019-05-16
      • 2021-09-16
      • 2017-08-23
      • 1970-01-01
      • 2021-08-08
      相关资源
      最近更新 更多