在material-ui中测试点击按钮后菜单消失(App工作,测试不工作)



我基于material-ui的示例创建了一个菜单组件,用于更改我的应用程序的简单菜单语言。该菜单在浏览器中工作得很好,但对于我的一个测试,更精确的最后断言,不工作,我不知道为什么。

测试应该:
  1. 渲染组件
  2. 测试菜单不呈现
  3. 点击菜单激活按钮
  4. 测试所呈现的菜单是否与快照匹配并且是可见的
  5. 点击菜单中的按钮关闭菜单(这里我尝试了不同的东西,没有注释)
  6. 测试菜单不再呈现,因此消失

在此代码状态之前,我在菜单的道具中有keepMounted,就像上面的链接示例一样,而不是测试菜单没有呈现,而是测试它是not.toBeVisible()。但这也行不通。

从错误消息中,我假设菜单中的按钮确实消失了,但菜单本身没有,因为按钮的HTML丢失了。但我不明白这是为什么。

我希望有人能解释一下这个问题。提前感谢:)

下面组件的代码在我的应用程序中工作,控制台输出来自下面的测试。

控制台输出:

FAIL  src/components/__tests__/LanguageMenu.test.tsx
<LanguageMenu />
× renders menu correctly when opened and closed (275 ms)
● <LanguageMenu /> › renders menu correctly when opened and closed
expect(received).toBeNull()
Received: <div aria-hidden="true" class="MuiPopover-root" data-testid="lang-menu" id="test-menu" role="presentation" style="position: fixed; z-index: 1300; right: 0px; bottom: 0px; top: 0px; left: 0px;"><div data-test="sentinelStart" tabindex="0" /><div class="MuiPaper-root MuiMenu-paper MuiPopover-paper MuiPaper-elevation8 MuiPaper-rounded" style="opacity: 0; transform: scale(0.75, 0.5625); transition: opacity 0ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,transform 0ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; top: 16px; left: 16px; transform-origin: -16px -16px;" tabindex="-1"><ul class="MuiList-root MuiMenu-list MuiList-padding" 
role="menu" tabindex="-1"><li aria-disabled="false" class="MuiButtonBase-root MuiListItem-root MuiMenuItem-root MuiMenuItem-gutters MuiListItem-gutters MuiListItem-button" role="menuitem" tabindex="0">Menu Button<span class="MuiTouchRipple-root"><span class="MuiTouchRipple-ripple MuiTouchRipple-rippleVisible" style="width: 2.8284271247461903px; height: 2.8284271247461903px; top: -1.4142135623730951px; left: -1.4142135623730951px;"><span class="MuiTouchRipple-child MuiTouchRipple-childLeaving" /></span></span></li></ul></div><div data-test="sentinelEnd" tabindex="0" /></div>
20 |     userEvent.click(screen.getByText("Menu Button"));
21 |
> 22 |     expect(screen.queryByTestId("lang-menu")).toBeNull();
|                                               ^
23 |   });
24 | });
25 |
at Object.<anonymous> (src/components/__tests__/LanguageMenu.test.tsx:22:47)
Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   1 passed, 1 total
Time:        6.587 s
Ran all test suites related to changed files.

菜单的简化版本重新创建问题:

import { Button, Menu, MenuItem, Typography } from "@material-ui/core";
import React, { MouseEvent, ReactElement, useState } from "react";
const LanguageMenu = (): ReactElement => {
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const handleClick = (event: MouseEvent<HTMLButtonElement>): void => {
setAnchorEl(event.currentTarget);
};
const handleClose = (): void => {
setAnchorEl(null);
};
return (
<>
<Button aria-controls="test-menu" aria-haspopup="true" onClick={handleClick}>
<Typography>Open Menu</Typography>
</Button>
<Menu
data-testid="lang-menu"
id="test-menu"
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClick={handleClose}
onClose={handleClose}
>
<MenuItem key="item1" onClick={handleClose}>
Menu Button
</MenuItem>
</Menu>
</>
);
};
export default LanguageMenu;

错误测试:

import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import React from "react";
import LanguageMenu from "../LanguageMenu";
describe("<LanguageMenu />", () => {
it("renders menu correctly when opened and closed", () => {
render(<LanguageMenu />);
expect(screen.queryByTestId("lang-menu")).toBeNull();
userEvent.click(screen.getByRole("button"));
expect(screen.getByTestId("lang-menu")).toMatchSnapshot();
expect(screen.getByTestId("lang-menu")).toBeVisible();
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// userEvent.click(screen.getByRole("presentation").firstChild); // click backdrop
// userEvent.click(screen.getByTestId("lang-menu")); // click menu itself
userEvent.click(screen.getByText("Menu Button")); // click button in menu
expect(screen.queryByTestId("lang-menu")).toBeNull();
});
});

在类似问题的答案之后,尝试在单击后等待值为空:

it("renders menu correctly when opened and closed", async () => {

...

userEvent.click(screen.getByText("Menu Button")); // click button in menu

await waitFor(() => expect(screen.queryByTestId("lang-menu")).toBeNull());
});

最新更新