【问题标题】:Testing styled components with react-testing-library使用 react-testing-library 测试样式化的组件
【发布时间】:2020-09-29 03:09:47
【问题描述】:

我目前正在尝试使用 Mocked Provider 测试样式化组件,如下所示:

import React from "react";
import TestResults from "./TestResults";
import {
  render,
  cleanup,
  findByTestId,
  findByText,
  waitForElement,
} from "@testing-library/react";
import { MockedProvider } from "@apollo/react-testing";




describe("TestResultsComponent", () => {
  describe("Overall", () => {
    it("should render successfully - base", async () => {
      const { getByText } = render(
        <MockedProvider>
          <TestResults />
        </MockedProvider>
      );
      expect(getByText("Preview")).toBeInTheDocument();
    });
  });
});

我在 TestResults 文件中使用 makeStyles 挂钩

当我运行测试时,我收到以下错误:

TypeError: theme.spacing is not a function
 Material-UI: the `styles` argument provided is invalid.
      You are providing a function without a theme in the context.
      One of the parent elements needs to use a ThemeProvider.

I'm not sure if I should mock out the implementation of makeStyles. This is the my first time seeing an error like this, I have been testing other components that use the same hook and it has not been an issue.

【问题讨论】:

    标签: reactjs unit-testing react-apollo apollo-client react-testing-library


    【解决方案1】:

    @material-ui/styles 样式解决方案是独立的,它对 Material-UI 组件一无所知。您需要将 style-components 包中的 ThemeProvider 与核心包中的 const theme = createMuiTheme() 函数一起使用,并在您的测试中渲染它。最好的情况是您已经在应用程序的某个地方定义了主题,并且可以简单地导入它。

    所以你的测试应该变成:

    import React from "react";
    import {ThemeProvider} from 'styled-components';
    import { createMuiTheme } from '@material-ui/core/styles';
    import TestResults from "./TestResults";
    import {
      render,
      cleanup,
      findByTestId,
      findByText,
      waitForElement,
    } from "@testing-library/react";
    import { MockedProvider } from "@apollo/react-testing";
    
    describe("TestResultsComponent", () => {
      describe("Overall", () => {
        it("should render successfully - base", async () => {
          const theme = createMuiTheme()
          const { getByText } = render(
            <ThemeProvider theme={muiTheme}>
              <MockedProvider>
                <TestResults />
              </MockedProvider>
            </ThemeProvider>
          );
          expect(getByText("Preview")).toBeInTheDocument();
        });
      });
    })
    

    如果这个用于包装组件的样板变得太多,您还可以编写一个 Wrapper-Component 来设置您需要的组件并将该组件作为第二个参数传递给 render-Options

    请参阅包装器的文档here

    【讨论】:

    • 感谢您的洞察@takethefake。从“@material-ui/styles”导入 ThemeProvider 与“styled-components”有什么区别?另外关于自定义主题的观点,我已经在我的应用程序中定义了它,所以我会将它作为主题道具传递给提供者。前任。
    【解决方案2】:

    感谢@takethefake 的回答,在我的情况下,我们没有使用 MaterialUi,但它非常相似:

    import React from 'react';
    import { render, screen } from '@testing-library/react';
    import { ThemeProvider } from 'styled-components';
    import { STRING } from '../constants';
    import Theme from '../styles/theme';
    import { PreOnboarding } from './PreOnboarding';
    
    test('la valeur `trigger.cta` est utilisée comme fallback du titre', () => {
      const trigger = { cta: 'fallback title', text: STRING.empty };
      const theme = Theme({ color1: 'red', color2: 'blue' });
    
      render(
        <ThemeProvider theme={theme}>
          <PreOnboarding trigger={trigger} />
        </ThemeProvider>
      );
      const button = screen.getByRole('label', { name: /fallback title/i });
      expect(button).toBeVisible();
    });
    

    【讨论】:

      猜你喜欢
      • 2019-06-14
      • 2019-09-20
      • 1970-01-01
      • 2019-05-21
      • 2019-11-11
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      相关资源
      最近更新 更多