使用react-testing-library测试styled components

5

我目前正试图使用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.
2个回答

13

@material-ui/styles 的样式解决方案是独立的,它不了解 Material-UI 组件。您需要使用 style-components 包中的ThemeProvider与来自核心包的 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();
    });
  });
})
如果这个用来包装你的组件的模板变得太多了,你也可以编写一个包装器组件,设置所需的组件并将此组件作为第二个参数传递给render-选项。
有关包装器的文档,请参见此处

谢谢你的洞察力 @takethefake。从"@material-ui/styles"导入ThemeProvider与从'styled-components'导入是否有区别?关于自定义主题,我已经在我的应用程序中定义了它,所以我会将它作为主题属性传递给提供者。例如:<ThemeProvider theme={customTheme}> - Francisco Banda

1
感谢@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();
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接