使用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: ""
原因与修复方案
核心问题
input[type="date"]的value格式限制:HTML原生日期输入框仅接受YYYY-MM-DD格式的字符串作为value,传入Date对象会被浏览器自动解析为空字符串,导致event.target.value无有效值。- fireEvent传参错误:触发change事件时,直接传递
Date对象给target.value,不符合输入框的格式要求。 - 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
相关产品推荐
相关产品推荐

