You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Testing Library无法修改Material UI DatePicker输入值问题求解

问题根因

这个报错有两个核心原因:

  • Material UI v4的DatePicker默认会给输入框添加readonly属性,浏览器会默认阻止只读输入框的change事件触发,所以直接调用fireEvent.change不会生效
  • 你当前测试里的DatePicker是受控组件写法,但value绑定了实时生成的new Date(),且onChange回调没有做状态更新逻辑,就算输入框事件能触发,组件值也不会同步更新

解决方法

方案1:模拟真实用户交互(推荐,更符合测试库的用户导向原则)

直接模拟用户正常选择日期的完整流程,不需要修改组件属性,和实际使用场景完全一致:

import React, { useState } from "react";
import { render, screen, fireEvent } from "@testing-library/react";

import MomentUtils from "@date-io/moment";
import { DatePicker, MuiPickersUtilsProvider } from "@material-ui/pickers";

describe("DatePicker", () => {
  test("Change datepicker value", async () => {
    // 封装带受控状态的测试组件
    const TestDatePicker = () => {
      const [date, setDate] = useState(new Date());
      return (
        <MuiPickersUtilsProvider utils={MomentUtils}>
          <DatePicker
            label="Start Date"
            id="startDate"
            onChange={(newDate) => setDate(newDate)}
            value={date}
            format={"yyyy/MM/DD"}
          />
        </MuiPickersUtilsProvider>
      )
    }

    render(<TestDatePicker />);
    const startDateInput = await screen.findByLabelText("Start Date");
    // 点击输入框调出日历面板
    fireEvent.click(startDateInput);
    // 找到对应日期元素点击,这里的aria-label格式和你用的日期工具库、语言配置有关,按需调整
    const targetDate = await screen.findByRole('gridcell', { name: /jan 1, 2021/i });
    fireEvent.click(targetDate);
    // 断言值正确
    expect(startDateInput).toHaveValue("2021/01/01");
  });
});

方案2:直接修改输入框值(适合快速测试输入场景)

如果不需要模拟面板选择,只想直接修改输入框的值,可以先移除输入框的readonly属性,再触发change事件:

import React, { useState } from "react";
import { render, screen, fireEvent } from "@testing-library/react";

import MomentUtils from "@date-io/moment";
import { DatePicker, MuiPickersUtilsProvider } from "@material-ui/pickers";

describe("DatePicker", () => {
  test("Change datepicker value", async () => {
    const TestDatePicker = () => {
      const [date, setDate] = useState(new Date());
      return (
        <MuiPickersUtilsProvider utils={MomentUtils}>
          <DatePicker
            label="Start Date"
            id="startDate"
            onChange={(newDate) => setDate(newDate)}
            value={date}
            format={"yyyy/MM/DD"}
          />
        </MuiPickersUtilsProvider>
      )
    }

    render(<TestDatePicker />);
    const startDateInput = (await screen.findByLabelText("Start Date")) as HTMLInputElement;
    // 先移除只读属性
    startDateInput.removeAttribute('readonly');
    // 再触发change事件
    fireEvent.change(startDateInput, { target: { value: "2021/01/01" } });
    // 触发blur事件让DatePicker完成值校验和同步
    fireEvent.blur(startDateInput);
    // 断言值正确
    expect(startDateInput.value).toBe("2021/01/01");
  });
});

内容的提问来源于stack exchange,提问作者jimmybutton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 12:57:02