ant design v4 打破了对 Select 和 Autocomplete 的反应测试库测试
Posted
技术标签:
【中文标题】ant design v4 打破了对 Select 和 Autocomplete 的反应测试库测试【英文标题】:ant design v4 breaks react testing library tests for Select and Autocomplete 【发布时间】:2020-07-19 15:36:39 【问题描述】:我最近将我的 React 项目升级到了 ant design v4,所有使用 Select、AutoComplete 或 Tooltip 的测试都被破坏了。基本上,当单击组件时,JSDOM 中不存在模式或选择选项。这在 v3 中可以正常工作。
有人可以告诉我如何使用 react 测试库测试 antd v4 吗?
示例:
我的组件:
import React from "react";
import "./styles.css";
import Select from "antd";
const Option = Select;
function handleChange(value)
console.log(`selected $value`);
export default function App()
return (
<div className="App" style= marginTop: "40px" >
<Select
defaultValue="lucy"
style= width: 120
onChange=handleChange
>
<Option value="jack">Jack</Option>
<Option value="lucy">Lucy</Option>
<Option value="disabled" disabled>
Disabled
</Option>
<Option value="Yiminghe">yiminghe</Option>
</Select>
</div>
);
我的测试
import "@testing-library/jest-dom/extend-expect";
import React from "react";
import render, fireEvent, prettyDOM from "@testing-library/react";
import App from "./App";
test("App Test", () =>
const queryAllByText, getByText, container = render(<App />);
expect(queryAllByText("Lucy").length).toBe(1);
expect(queryAllByText("Jack").length).toBe(0);
fireEvent.click(getByText("Lucy"));
console.log(prettyDOM(container));
// This line fails although I would expect the dropdown to be open and all the options visible
expect(queryAllByText("Jack").length).toBe(1);
);
这里是重现问题的代码框的链接。 (如前所述,该代码曾经在 v3 中工作)。
https://codesandbox.io/s/staging-shape-0xkrl?file=/src/App.test.js:0-494
【问题讨论】:
【参考方案1】:在这失去了 2 天之后,这是问题和解决方案:
问题
在 antd v3 中,过去可以通过 selecthtmlElement.click()
打开 Select。您可以在 chrome 开发工具控制台中进行测试。在 v4 中,这不起作用。
这意味着在底层使用 JSDOM 的 RTL 将具有相同的行为。当你这样做时fireEvent.click(selectElement);
什么都没有发生!
解决方案
这让我走上了正轨:https://github.com/ant-design/ant-design/issues/22074
您需要触发的事件不是click()
,而是选择的第一个孩子上的mouseDown()
。
const elt = getByTestId('your-select-test-id').firstElementChild;
fireEvent.mouseDown(elt); // THIS WILL OPEN THE SELECT !
此时,您可能想从列表中选择一个选项,但有一个动画正在进行,因此以下代码(以前在 v3 中工作)也将失败。
expect(getByText('Option from Select')).toBeVisible(); // FAILS !
您有 2 个选项,使用 toBeInTheDocument()
或使用 waitFor(...)
等待动画结束
选项 1:更快但不完全准确,我更喜欢将其用于简单的用例,因为它使测试更快且同步
expect(getByText('Option from Select')).toBeInTheDocument(); // WORKS !
选项 2:因为您需要等待动画完成,所以速度较慢,但在复杂情况下更准确
await waitFor(() => expect(getByText('Option from Select')).toBeVisible()); // WORKS !
【讨论】:
值得一提的是 fireEvent.change(elt.querySelector('input'), target:value:'Option text') 适用于可搜索的选择(只有正确的选项可见,并准备好被点击)。 完美运行,但您也可以使用setInterval(() => expect(), 0)
,而不是await waitFor()
,您也可以将open
属性设置为true
,而不是执行mouseDown
事件跨度>
工具提示怎么样?你知道如何测试它吗?即使我输入了 data-testid @klugjo,我似乎也无法在测试中找到工具提示
感谢您的 2 天,我只损失了 20 分钟,谢谢您!
其实我可以userEvent.click
(import userEvent from '@testing-library/user-event'
)打开下拉菜单,但是当我尝试点击选项时,出现unsable to focus
的错误。【参考方案2】:
现在看起来 ("antd": "4.17.3", "@testing-library/user-event": "^13.5.0") userEvent.click
和 skipPointerEventsCheck: true
工作:
const options = [
label: "?", value: "cat", ,
label: "?", value: "dog",
];
const onChangeMock = jest.fn();
render(
<Select
options=options
onChange=onChangeMock
/>,
);
const select = screen.getByRole("combobox");
userEvent.click(select);
const option = screen.getByText("?");
userEvent.click(option, undefined, skipPointerEventsCheck: true );
expect(onChangeMock).toHaveBeenCalledWith("dog",
label: "?",
value: "dog",
);
【讨论】:
【参考方案3】:不幸的是,@klugjo 的答案对我来说不适用于 antd-mobile 的 Radio
组件。
我通过向组件添加额外的onClick
属性解决了这个问题:
<Radio.RadioItem
key=key
checked=isSelected
onChange=onChange
onClick=onChange // needed for rtl
>
label
</Radio.RadioItem>
这不是一个干净的解决方案,因为它会修改生产代码以进行测试。它可能会错过 TouchEvent
的失败,但这应该是 antd-mobile 库的问题——不是这个测试。
【讨论】:
以上是关于ant design v4 打破了对 Select 和 Autocomplete 的反应测试库测试的主要内容,如果未能解决你的问题,请参考以下文章
Ant Design Pro V4.5 获取和设置ProFormSelect选项(typescript版)
Ant Design Pro V4.5 从服务器请求菜单(typescript版)
Ant Design Pro V4.5 从服务器请求菜单(typescript版)