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(() =&gt; expect(), 0),而不是await waitFor(),您也可以将open 属性设置为true,而不是执行mouseDown 事件跨度> 工具提示怎么样?你知道如何测试它吗?即使我输入了 data-testid @klugjo,我似乎也无法在测试中找到工具提示 感谢您的 2 天,我只损失了 20 分钟,谢谢您! 其实我可以userEvent.clickimport 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版)

Ant Design Pro V4.5 从服务器请求菜单图标不显示解决

antd v3 升级 v4

Ant Design Pro V4.5 从服务器请求数据的坑(typescript版)