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

使用fireEvent.change()触发输入变更时event.target.value为undefined问题

问题:fireEvent.change()触发日期输入变更时,值未正确更新且event.target.value异常

复现代码

import "@testing-library/jest-dom/extend-expect";
import React from "react";
import {
  fireEvent,
  render,
} from "@testing-library/react";

jest.mock('@material-ui/pickers', () => {
  const MockedMuiPickersUtilsProvider = ({ children }) => {
    return <div data-testid="mocked-mui-pickers-utils-provider">{children}</div>;
  };

  const MockedDatePicker = ({ onChange, value }) => {
    const handleDateChange = (event) => {
      const selectedDate = event.target.value;
      console.log('Selected Date: ', selectedDate);
      onChange(selectedDate);
    };
    
    return (
      <input
        value={value}
        type="date"
        onChange={handleDateChange}
        data-testid='my-datepicker-test-id'
      />
    );
  };
  return { MuiPickersUtilsProvider: MockedMuiPickersUtilsProvider, DatePicker: MockedDatePicker };
});

describe("Input date", () => {
  it('input value should be defined', async () => {
    const component = render(<MyComponent />);
    const inputDate = component.getByTestId('my-datepicker-test-id');
    const date = new Date('2023-07-18');

    fireEvent.change(inputDate, { target: { value: date } });

    expect(inputDate.value).toBe(date);
  });
});

测试失败结果

FAIL

expect(received).toBe(expected)

Expected: 2023-08-18T00:00:00.000Z
Received: ""

原因与修复方案

核心问题

  1. input[type="date"]的value格式限制:HTML原生日期输入框仅接受YYYY-MM-DD格式的字符串作为value,传入Date对象会被浏览器自动解析为空字符串,导致event.target.value无有效值。
  2. fireEvent传参错误:触发change事件时,直接传递Date对象给target.value,不符合输入框的格式要求。
  3. Mock组件的value处理缺失:如果父组件MyComponent传给DatePicker的是Date对象,Mock的input无法直接解析该值,会显示为空。

具体修复步骤

1. 修正fireEvent的传参格式

将Date对象转换为YYYY-MM-DD格式的字符串:

const date = new Date('2023-07-18');
// 提取ISO字符串中的日期部分,得到YYYY-MM-DD格式
const dateStr = date.toISOString().split('T')[0];

fireEvent.change(inputDate, { target: { value: dateStr } });

2. 调整Mock组件的事件处理逻辑

日期输入框返回的event.target.value是字符串,若需要传给父组件Date对象,需手动转换:

const handleDateChange = (event) => {
  const selectedDateStr = event.target.value;
  // 将字符串转为Date对象后传递
  const selectedDate = new Date(selectedDateStr);
  console.log('Selected Date: ', selectedDate);
  onChange(selectedDate);
};

3. 修正断言逻辑

输入框的value是字符串类型,断言需匹配对应格式:

expect(inputDate.value).toBe(dateStr);

4. 优化Mock组件的value接收逻辑

如果父组件传入的是Date对象,提前转换为输入框支持的字符串格式:

const MockedDatePicker = ({ onChange, value }) => {
  // 将Date对象转为YYYY-MM-DD字符串,非Date类型直接使用
  const inputValue = value instanceof Date ? value.toISOString().split('T')[0] : value;
  
  const handleDateChange = (event) => {
    const selectedDateStr = event.target.value;
    const selectedDate = new Date(selectedDateStr);
    onChange(selectedDate);
  };
  
  return (
    <input
      value={inputValue}
      type="date"
      onChange={handleDateChange}
      data-testid='my-datepicker-test-id'
    />
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 12:45:55