[英]React testing library, how to open a Collapse in Ant Design
I want to write a unit test that opens an antd.我想写一个打开antd的单元测试。 Collapse
<Panel />
折叠
<Panel />
But no matter what combination of fireEvent or userEvent mouse actions I try, I cannot get React testing library to properly "click" on this antD component the same way a real user does.但是无论我尝试使用什么组合的 fireEvent 或 userEvent 鼠标操作,我都无法让 React 测试库像真实用户一样正确地“点击”这个 antD 组件。
Example code:示例代码:
import { Collapse } from 'antd'
const { Panel } = Collapse
const Example = () => (
<Collapse>
<Panel header="test" data-testid="testid">hello_world</Panel>
</Collapse>
)
and in my unit test:在我的单元测试中:
I have tried the following combinations to open the Panel with the header "test"我尝试了以下组合来打开带有标题“test”的面板
const panel = screen.getByText('test')
userEvent.click(panel)
const result = screen.getByText('hello_world') // FAILED and never finds hello_world
const panel = screen.getByText('test')
userEvent.click(panel)
const result = await screen.findByText('hello_world') // FAILED and never finds hello_world
const panel = screen.getByText('test')
fireEvent.click(panel)
const result = await screen.findByText('hello_world') // FAILED and never finds hello_world
const panel = screen.getByText('test')
fireEvent.mouseDown(panel)
const result = await screen.findByText('hello_world') // FAILED and never finds hello_world
const panel = screen.getByText('test')
await act(async () => {
fireEvent.mouseDown(panel)
})
const result = await screen.findByText('hello_world') // FAILED and never finds hello_world
const panel = screen.getByText('test')
await act(async () => {
fireEvent.mouseDown(panel)
})
await waait(500) // using waait library, to force time to pass to see if it was that...
const result = await screen.findByText('hello_world') // FAILED and never finds hello_world
const panel = screen.getByTestId('testid')
fireEvent.click(panel) // FAILED, never finds anything with data-testid="testid"
// I guess antd did not bother passing the test-id to the component.
const result = await screen.findByText('hello_world')
This is what the HTML looks like:这是 HTML 的样子:
<div
class="ant-collapse ant-collapse-icon-position-left css-14dabdk"
>
<div
class="ant-collapse-item"
>
<div
aria-expanded="false"
class="ant-collapse-header"
role="button"
tabindex="0"
>
test
</div>
</div>
I did also try to use querySelector
on container
to target .ant-collapse-header
, ant-collapse-item
or .ant-collapse
with userEvent.click and fireEvent.mouseDown.我还尝试在
container
上使用querySelector
来定位.ant-collapse-header
、 ant-collapse-item
或.ant-collapse
以及 userEvent.click 和 fireEvent.mouseDown。 But those didn't work either.但那些也没有用。
Why is this thing so difficult to open in a test 🤯.为什么这个东西在测试中这么难打开🤯。
Does anyone know how to open and antD Collapse component?有谁知道如何打开和 antD Collapse 组件?
Using user-event
, you can try:使用
user-event
,您可以尝试:
await userEvent.click(screen.getByText(/test/i))
Or click the button, like:或单击按钮,例如:
await userEvent.click(screen.getByRole("button"))
Then you can use findByText
like:然后你可以使用
findByText
像:
expect(await screen.findByText(/hello_world/i)).toBeInTheDocument();
( Working example ) ( 工作示例)
I've created a simple example to simulate your issue.我创建了一个简单的示例来模拟您的问题。
What i did to get it working:我做了什么让它工作:
getByText
, queryByText
and findByText
direct from the return of render, like const { getByText, queryByText } = render(<Example />);
getByText
, queryByText
和findByText
直接从渲染的返回,如const { getByText, queryByText } = render(<Example />);
* but you can use screen
, not problem at all. * 但你可以使用
screen
,一点问题都没有。
async
, like:async
,例如:it("test", async () => { ... })
or或者
test("test", async () => { ... })
getByText
with waitFor
or findByText
, like below:getByText
与waitFor
或findByText
一起使用,如下所示: Code:代码:
describe("Test PANEL", () => {
it("should PASS WITH QUERYBY - hello_world RENDERED after CLICKED", async () => {
const { getByText, queryByText } = render(<Example />);
const panel = getByText("test");
fireEvent.click(panel);
await waitFor(() => {
const result = queryByText("hello_world");
expect(result).toBeInTheDocument();
});
});
it("should PASS WITH FINDBY - hello_world RENDERED after CLICKED", async () => {
const { getByText, findByText } = render(<Example />);
const panel = getByText("test");
fireEvent.click(panel);
const result = await findByText("hello_world");
expect(result).toBeInTheDocument();
});
});
If you want to check if 'hello_world' is not rendered yet, i recommend you use queryBy
, like this:如果您想检查 'hello_world' 是否尚未呈现,我建议您使用
queryBy
,如下所示:
describe("Test PANEL", () => {
it("should PASS - hello_world NOT redenred before CLICKED", async () => {
const { getByText, queryByText } = render(<Example />);
const panel = getByText("test");
expect(panel).toBeInTheDocument();
await waitFor(() => {
const result = queryByText("hello_world");
expect(result).not.toBeInTheDocument();
});
});
That´s because queryBy
returns null if it doesnt find any Element, different than findBy
and getBy
-> both throws an error, as you can see in this link .那是因为如果
queryBy
没有找到任何元素,则返回 null,这与findBy
和getBy
不同 -> 都会引发错误,如您在此链接中所见。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.