【问题标题】:How to test ant design date picker using @testing-library/react?如何使用@testing-library/react 测试 ant 设计日期选择器?
【发布时间】:2022-02-18 17:42:32
【问题描述】:

我在一个组件中有两个 ant design date pickers。我正在尝试更改和测试日期选择器的值,但无法在测试环境 dom 中找到日历输入。

日期选择器组件

import { DatePicker, Form } from "antd";
import React, { Component } from "react";

import moment from "moment";

class DatePickers extends Component {
  constructor(props) {
    super(props);
    this.state = {
      startDate: moment().subtract(1, "month"),
      startDateError: "",
      endDate: moment(),
      endDateError: "",
    };
  }

  onStartDateChange = (date) => {
    this.setState({
      startDate: date,
      startDateError: date ? "" : "Please select start date",
    });
  };

  onEndDateChange = (date) => {
    this.setState({
      endDate: date,
      endDateError: date ? "" : "Please select end date",
    });
  };

  render() {
    const { endDate, endDateError, startDate, startDateError } = this.state;

    return (
      <React.Fragment>
        <Form.Item
          validateStatus={startDateError ? "error" : ""}
          help={startDateError}
          htmlFor="startDate"
          label="Date From"
        >
          <DatePicker
            id="startDate"
            placeholder="Select Start Date"
            allowClear={false}
            onChange={this.onStartDateChange}
            defaultPickerValue={startDate}
            defaultValue={startDate}
            format="DD-MM-YYYY"
          />
        </Form.Item>
        <Form.Item
          validateStatus={endDateError ? "error" : ""}
          help={endDateError}
          htmlFor="endDate"
          label="To"
        >
          <DatePicker
            id="endDate"
            placeholder="Select End Date"
            allowClear={false}
            onChange={this.onEndDateChange}
            defaultPickerValue={endDate}
            defaultValue={endDate}
            format="DD-MM-YYYY"
          />
        </Form.Item>
      </React.Fragment>
    );
  }
}


export default DatePickers;

使用@testing-library/react 的测试用例

import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

test("date input value validation", async () => {
  const { container } = render(<DatePickers />);

  const startDateNode = screen.getByPlaceholderText(/select start date/i);
  const endDateNode = screen.getByPlaceholderText(/select end date/i);

  userEvent.click(startDateNode);

  const calendarInput = container.querySelector("ant-calendar-input");
  await userEvent.type(calendarInput, "");

  // assert
  expect(screen.getByText("Please select by start date")).toBeInTheDocument();
});

测试用例失败并抛出错误

console.error node_modules/jest-environment-jsdom-fourteen/node_modules/jsdom/lib/jsdom/virtual-console.js:29
      Error: Not implemented: navigation (except hash changes)

版本:

"react" : "16.10.1",
"antd": "3.25.1",
"@testing-library/jest-dom": "5.7.0",
"@testing-library/react": "10.0.4",
"@testing-library/user-event": "10.1.2"

有什么解决方案可以断言这一点吗?

【问题讨论】:

    标签: reactjs jestjs antd react-testing-library


    【解决方案1】:

    我在使用 antd v4 时遇到了完全相同的问题。上述解决方案很合适并且可以正常工作。我在 Form.Item 中使用多个日期选择器时遇到了一些问题,如果我们对 Datepicker 进行自定义验证,请确保正确设置日期格式。

        const startDate = screen.getByTestId("start-date");
        fireEvent.mouseDown(startDate);
        fireEvent.change(startDate, { target: { value: "10-12-2020" } });
        fireEvent.click(document.querySelectorAll(".ant-picker-cell-selected")[0]);
    

    设置日期时,请确保值是正确的格式,根据您的验证,并确保如果不使用时刻,所有日期字符串都设置为您使用的任何库。我正在使用 dayjs,并且有一个对象弄乱了其中一个日期。我花了几个小时才弄明白。希望对您有所帮助。

        const endDate = screen.getByTestId("end-date");
        fireEvent.mouseDown(endDate);
        fireEvent.change(endDate, { target: { value: "10-25-2020" } });
        fireEvent.click(document.querySelectorAll(".ant-picker-cell-selected")[1]);
    
    

    【讨论】:

    • 对我来说,无论出于何种原因,使用fireEvent.mouseDown()fireEvent.change() 都很重要。我一直在尝试使用userEvent.click()userEvent.type() 无济于事。也许这对某人有帮助。
    【解决方案2】:

    此错误似乎与日期选择器测试问题无关:https://github.com/jsdom/jsdom/issues/2112

    无论如何,这就是我使用 RTL 测试 Ant Design 日期选择器的方式:

    以下代码适用于 antd v4

    组件

    <Form.Item colon={false} label={t('searchFields.creationDate.label')} name="creationDateRange">
      <RangePicker data-testid="creationDate" />
    </Form.Item>
    

    测试

    [...]
    rtl = render(...);
    [...]
    
    // grab the input
    const creationDateFromInput = rtl.getByTestId('creationDate').querySelectorAll('input')[0];
    // mouseDown opens the calendar popup, set focus on the input
    fireEvent.mouseDown(creationDateFromInput);
    // type date in input
    fireEvent.change(creationDateFromInput, { target: { value: '2020-01-15' } });
    // now calendar popup is opened and 2020-01-15 cell is selected, just click on it
    fireEvent.click(document.querySelector('.ant-picker-cell-selected'));
    
    // now form field is correclty set
    

    我试图使它更具可读性并避免使用我不太喜欢的 document.querySelector 部分,但我找不到其他解决方案。这当然可以改进。

    祝你好运

    【讨论】:

    • 我尝试将您的解决方案与 DatePicker 集成,但没有成功。另外,我试图找到.ant-calendar-selected-date,而不是.ant-picker-cell-selected
    • 我知道你使用的是 antd 3,我使用的是 antd 4,所以你可能确实需要稍微调整一下选择器。
    猜你喜欢
    • 2019-08-29
    • 2021-11-30
    • 2019-05-21
    • 2019-11-11
    • 2020-08-03
    • 2019-10-30
    • 2021-02-11
    • 2022-08-04
    • 2023-04-04
    相关资源
    最近更新 更多