React测试库,如何在Ant Design中打开一个Collapse
React testing library, how to open a Collapse in Ant Design
我想写一个打开antd的单元测试。收起 <Panel />
但无论我尝试使用何种 fireEvent 或 userEvent 鼠标操作组合,我都无法让 React 测试库以与真实用户相同的方式正确地“单击”这个 antD 组件。
示例代码:
import { Collapse } from 'antd'
const { Panel } = Collapse
const Example = () => (
<Collapse>
<Panel header="test" data-testid="testid">hello_world</Panel>
</Collapse>
)
在我的单元测试中:
我尝试了以下组合来打开带有 header“测试”
的面板
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')
这就是 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>
我也曾尝试在 container
上使用 querySelector
以 .ant-collapse-header
、ant-collapse-item
或 .ant-collapse
与 userEvent.click 和 fireEvent.mouseDown。但是那些也不管用。
为什么这个东西在测试中这么难打开。
有谁知道如何打开和antD Collapse组件吗?
使用user-event
,你可以试试:
await userEvent.click(screen.getByText(/test/i))
或点击按钮,如:
await userEvent.click(screen.getByRole("button"))
然后你可以使用 findByText
比如:
expect(await screen.findByText(/hello_world/i)).toBeInTheDocument();
我创建了一个简单示例来模拟您的问题。
我做了什么让它工作:
- 而不是屏幕,我使用
getByText
、queryByText
和 findByText
直接来自渲染的 return,例如 const { getByText, queryByText } = render(<Example />);
* 但你可以使用 screen
,完全没有问题。
- 你的功能测试应该是
async
,比如:
it("test", async () => { ... })
或
test("test", async () => { ... })
- 要测试渲染 'Hello world' 是否成功,您可以将
getByText
与 waitFor
或 findByText
一起使用,如下所示:
代码:
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();
});
});
如果你想检查 '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();
});
});
那是因为如果 queryBy
return 没有找到任何元素,则为 null,不同于 findBy
和 getBy
-> 两者都会抛出错误,因为您可以在这个link.
看到
我想写一个打开antd的单元测试。收起 <Panel />
但无论我尝试使用何种 fireEvent 或 userEvent 鼠标操作组合,我都无法让 React 测试库以与真实用户相同的方式正确地“单击”这个 antD 组件。
示例代码:
import { Collapse } from 'antd'
const { Panel } = Collapse
const Example = () => (
<Collapse>
<Panel header="test" data-testid="testid">hello_world</Panel>
</Collapse>
)
在我的单元测试中:
我尝试了以下组合来打开带有 header“测试”
的面板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')
这就是 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>
我也曾尝试在 container
上使用 querySelector
以 .ant-collapse-header
、ant-collapse-item
或 .ant-collapse
与 userEvent.click 和 fireEvent.mouseDown。但是那些也不管用。
为什么这个东西在测试中这么难打开。
有谁知道如何打开和antD Collapse组件吗?
使用user-event
,你可以试试:
await userEvent.click(screen.getByText(/test/i))
或点击按钮,如:
await userEvent.click(screen.getByRole("button"))
然后你可以使用 findByText
比如:
expect(await screen.findByText(/hello_world/i)).toBeInTheDocument();
我创建了一个简单示例来模拟您的问题。
我做了什么让它工作:
- 而不是屏幕,我使用
getByText
、queryByText
和findByText
直接来自渲染的 return,例如const { getByText, queryByText } = render(<Example />);
* 但你可以使用 screen
,完全没有问题。
- 你的功能测试应该是
async
,比如:
it("test", async () => { ... })
或
test("test", async () => { ... })
- 要测试渲染 'Hello world' 是否成功,您可以将
getByText
与waitFor
或findByText
一起使用,如下所示:
代码:
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();
});
});
如果你想检查 '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();
});
});
那是因为如果 queryBy
return 没有找到任何元素,则为 null,不同于 findBy
和 getBy
-> 两者都会抛出错误,因为您可以在这个link.