使用 react-testing-library 测试样式化的组件
Posted
技术标签:
【中文标题】使用 react-testing-library 测试样式化的组件【英文标题】:Testing styled components with 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.
【问题讨论】:
【参考方案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”有什么区别?另外关于自定义主题的观点,我已经在我的应用程序中定义了它,所以我会将它作为主题道具传递给提供者。前任。感谢@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();
);
【讨论】:
以上是关于使用 react-testing-library 测试样式化的组件的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 React-Testing-Library 测试 mapDispatchToProps?
如何使用 Jest 和 react-testing-library 测试 useRef?
react-testing-library - 屏幕与渲染查询
如何使用 react-testing-library 测试由其他组件组成的组件?