首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用@testing/react中的sx道具测试资料UI v5组件?

如何使用@testing/react中的sx道具测试资料UI v5组件?
EN

Stack Overflow用户
提问于 2022-02-22 08:03:23
回答 2查看 1.1K关注 0票数 9

React测试库在呈现过程中不应用材料UI组件的sx支持。

例如,我指定属性来隐藏某个断点上的元素。

代码语言:javascript
复制
<>
  <AppBar
    data-testid="mobile"
    ...
    sx={{
      display: { xs: "block", sm: "none" }
    }}
  >
    MOBILE
  </AppBar>
  <AppBar
    data-testid="desktop"
    ...
    sx={{
      display: { xs: "none", sm: "block" }
    }}
  >
    DESKTOP
  </AppBar>
</>

在浏览器中,一切都按预期工作。当呈现在React测试库中时,我得到了两个元素的结果。从样式中可以清楚地看出,它们是基础知识,而sx属性没有应用。链接到码箱

代码语言:javascript
复制
import { ThemeProvider } from "@mui/material/styles";
import { screen, render } from "@testing-library/react";
import darkTheme from "./darkTheme";
import App from "./App";

describe("Demo", () => {
  it("should have display props", () => {
    render(
      <ThemeProvider theme={darkTheme}>
        <App />
      </ThemeProvider>
    );

    expect(screen.getByTestId("mobile")).toHaveStyle({ display: "none" });
    expect(screen.getByTestId("desktop")).toHaveStyle({ display: "block" });
  });
});

测试结果

在中测试这种材料UI道具的正确方法是什么?

EN

回答 2

Stack Overflow用户

发布于 2022-06-02 12:46:40

在遇到同样的问题后,我决定编写一个临时帮助程序,用于对计算样式执行断言。

我发现正在将计算出来的sx样式应用于head。如果你运行screen.debug(),你将无法看到它.然而,运行document.head.innerHTML就能做到这一点。

请注意,这一用途远远不是完美的。这只是继续测试的一种快速方法。

代码语言:javascript
复制
export const getElementStyleFromHead = (element: HTMLElement) => {
  const sourceElementClassNames = [...element.classList.values()]; // get all the classNames for source element
  const styleTags = new DOMParser().parseFromString(document.head.innerHTML, 'text/html').querySelectorAll('style'); // parse all style tags in head
  const styleTagsArray = [...styleTags.values()]; // convert NodeList to array
  const elementStyles = styleTagsArray.filter((style) => sourceElementClassNames.some((className) => style.innerHTML?.includes(className))); // filter all matching classNames between sourceElementClassNames and the style tag
  return elementStyles.map(item => item.innerHTML).join(''); // join all classes and parse it as one css string
};

页面:

代码语言:javascript
复制
<Box sx={{ 
  display: 'flex', 
  justifyContent: centerContent ? 'center' : 'flex-start'
 }}>
  {'dummy content'}
</Box>

使用它:

代码语言:javascript
复制
    expect(getElementStyleFromHead(customScreen.getByText('dummy content'))).toContain('justify-content:center')

编辑:我发现动态风格并不总是被及时清理。我的用例是,当我在内容窗格中滚动时,应该使用:after和: case将滚动指示器(阴影)添加到窗格的顶部和底部。我的测试没有按顺序运行,但在隔离运行时却通过了。我在beforeEach中添加了这一行,以确保头部始终被清除。不确定这是否还有其他副作用..。

代码语言:javascript
复制
beforeEach(() => {
    document.head.innerHTML = '';
});
票数 0
EN

Stack Overflow用户

发布于 2022-11-10 22:04:49

如果您想测试屏幕大小,您可能必须移动逻辑以检测屏幕大小。

如果您使用windows.innerWidth,然后在此基础上显示您的元素。

代码语言:javascript
复制
const mobileScreenSize = someNumberYouPick
const screenSize = window.innerWidth;

const mobile = () => { return screenSize - mobileScreenSize =< 0 ? true : false}

{ mobile() && {
<AppBar
    data-testid="mobile"
    ...
  >
    MOBILE
  </AppBar>
}}

{ !mobile() && {
<AppBar
    data-testid="desktop"
    ...
  >
    DESKTOP
  </AppBar>
}}

然后在测试中,您可以设置您的windows.innerwidth并设置您想要的值。

代码语言:javascript
复制
describe("Demo", () => {
  it("should have display props", () => {

Object.defineProperty(window, 'innerWidth', {
        writable: true,
        configurable: true,
        value: 150,
      });

    render(
      <ThemeProvider theme={darkTheme}>
        <App />
      </ThemeProvider>
    );
expect(screen.getByTestId("mobile")).not.toBeVisible() 
expect(screen.getByTestId("desktop")).toBeVisible()

  });
});

这应该能起作用。如果使用以下方法设置测试,我想知道是否需要更改代码逻辑:

代码语言:javascript
复制
Object.defineProperty(window, 'innerWidth', {
        writable: true,
        configurable: true,
        value: 150,
      });
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71217789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档