【问题标题】:Testing disabled button reactjs测试禁用按钮reactjs
【发布时间】:2021-12-14 08:33:04
【问题描述】:

我有一个 React 导出按钮组件,当 totalRecords 超过 ORDER_LIMIT 或等于 0 时,它将被禁用。代码如下所示:

interface ExportExcelButtonProps {
  filterValues: OrderFilter;
  totalOrders: number;
}

const ExportExcelButton: React.FC<ExportExcelButtonProps> = ({ filterValues, totalOrders }) => {
  const [loading, setLoading] = useState<boolean>(false);
  const disabled = totalOrders === 0 || totalOrders > ORDER_LIMIT;
  
  const onExportBtnClick = async () => {
    ...
  };

  return (
   <Button
      disabled={disabled}
      loading={loading}
      onClick={onExportBtnClick}
      type="primary"
      icon={<DownloadOutlined />}
      data-testid="export-btn"
    >
      {t("ExportExcel")}
    </Button>
  );
};

父组件中的代码:

    const { orders, filters, pagination } = useOrderData(); // Fetch order data from this hook
    const totalOrders = pagination.total || 0;
    ....
    <ExportExcelButton filterValues={filters} totalOrders={totalOrders} />

我正在尝试通过这样的测试用例来测试我的 ExportExcelButton:

   it("exports by orderDate", async () => {
    const dummyDateRange = [dayjs("2020-10-20T00:00:00+07:00"), dayjs("2020-10-30T23:59:59+07:00")];
    fireEvent.change(orderDateField, { target: { value: "1", payload: dummyDateRange } });

    userEvent.click(searchButton);
    await waitFor(() => {
      expect(getOrdersMock).toHaveBeenCalled();
    });

    await waitFor(() => {
      expect(exportButton).toBeEnabled();
    });

    userEvent.click(exportButton);
    await waitFor(() => {
      const params = {
        startDate: dummyDateRange[0].format(),
        endDate: dummyDateRange[1].format(),
        limit: ORDER_LIMIT,
      };
      expect(exportOrdersMock).toBeCalledWith(expect.objectContaining(params));
    });
  });

当我运行测试文件时,上面的测试用例失败了,因为导出按钮仍然被禁用

  expect(element).toBeEnabled()
    Received element is not enabled:
      <button class="ant-btn ant-btn-primary" data-testid="export-btn" disabled="" style="pointer-events: none;" type="button" />

但是当我签入快照文件时,这个按钮没有disabled 属性:

 <button
   class="ant-btn ant-btn-primary"
   data-testid="export-btn"
   type="button"
 >

我已经在getOrdersMock 中使用totalOrders = 1 模拟数据。我认为当totalOrders 在测试期间更改时组件ExportExcelButton 没有更新。如何使ExportExcelButton 更新?还有其他方法可以测试这种情况吗?

【问题讨论】:

  • 什么是 ORDER_LIMIT?尝试console.log(disabled, totalOrders),它记录了什么?
  • 我设置 ORDER_LIMIT = 500,当我登录 console.log(disabled, totalOrders) 时,首先它记录了 'true 0' ,最后它记录了 'false 1'
  • 也许你应该创建一个代码框
  • 抱歉,由于代码库大,我无法提供代码框,顺便说一下,我通过在 expect(exportButton).toBeEnabled() 行之前从快照中获取 exportButton 找到了解决方案。感谢您的帮助。

标签: javascript reactjs typescript testing


【解决方案1】:

问题来了:

 beforeEach(() => {
  getOrdersMock = jest.spyOn(orderApis, "getOrdersList");
  exportOrdersMock = jest.spyOn(orderApis, "exportOrders");

  ({ container } = render(
    <Router>
      <OrderList />
    </Router>
  ));

  exportButton = screen.getByTestId("export-btn") as HTMLButtonElement;
});

我在beforeEach中定义的exportButton只在第一次渲染时捕获快照,点击searchButton后,快照将被更新。因此,我必须再次从快照中获取我的exportButton。

    userEvent.click(searchButton);
    await waitFor(() => {
      expect(getOrdersMock).toHaveBeenCalled();
    });

    exportButton = screen.getByTestId("export-btn") as HTMLButtonElement; // add this line
    
    await waitFor(() => {
      expect(exportButton).toBeEnabled();
    });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-02
    • 2018-12-07
    • 1970-01-01
    • 2021-02-22
    • 1970-01-01
    • 1970-01-01
    • 2019-03-29
    相关资源
    最近更新 更多