如何用Jest测试日期?日期比较测试遇类型错误求助
问题
我正在编写测试用例,验证选中的日期是否大于当前日期。以下是待测试的React组件代码:
const [selectedDate, setSelectedDate] = useState<Moment>(); <TimeComponent> <SetTimeButton data-testid="scheduleTime" onClick={() => scheduleTimeHandler( selectedDate, timeSelect, setSelectedDate, setTimeDialog, setDisableConfirm ) } /> <DisplayDate data-testid="selectedDate">{selectedDate}</DisplayDate> </TimeComponent>
这是我编写的Jest测试代码:
import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; import TimeComponent from './TimeComponent'; test('set schedule time', () => { render( //@ts-ignore <TimeComponent /> ); const mockDateObject = new Date(); const scheduleTimeBtn = screen.queryByTestId('scheduleTime'); const selectedDate = screen.queryByTestId('selectedDate'); fireEvent.click(scheduleTimeBtn); expect(selectedDate).toBeGreaterThan(+mockDateObject); });
执行测试时,expect语句中针对selectedDate出现如下错误:
expect(received).toBeGreaterThan(expected)
Matcher error: received value must be a number or bigint
Received has value: null
我知道这是因为selectedDate是HTML元素而非日期值,但不清楚如何将其转为日期值进行测试,请问我哪里出错了?
解决方案
你的测试代码存在两个核心问题,修正后即可正常运行:
1. 元素获取时机错误
你在点击按钮前就调用screen.queryByTestId('selectedDate')获取元素,此时组件还未触发状态更新,selectedDate为空,所以返回null。正确做法是在点击按钮后再获取目标元素,或者使用screen.getByTestId(它会自动等待元素渲染完成,比queryBy更适合处理交互后的异步更新场景)。
2. 未提取日期文本并转为可比较格式
queryByTestId返回的是DOM元素对象,而非日期值。你需要先提取元素的文本内容,再将其转换为与组件一致的Moment对象(或时间戳),才能进行日期比较。
修改后的测试代码
import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; import TimeComponent from './TimeComponent'; import moment from 'moment'; // 组件使用Moment类型,需引入对应库 test('set schedule time', () => { render( //@ts-ignore <TimeComponent /> ); const currentDate = moment(); // 用moment创建当前日期,与组件类型对齐 const scheduleTimeBtn = screen.getByTestId('scheduleTime'); fireEvent.click(scheduleTimeBtn); // 点击后获取元素,提取文本并转为Moment对象 const selectedDateElement = screen.getByTestId('selectedDate'); const selectedDate = moment(selectedDateElement.textContent); // 用moment内置的isAfter方法比较,更符合Moment类型的使用习惯 expect(selectedDate.isAfter(currentDate)).toBe(true); // 也可以转换为时间戳用数值比较: // expect(selectedDate.valueOf()).toBeGreaterThan(currentDate.valueOf()); });
额外注意事项
- 如果
DisplayDate组件对日期做了自定义格式化(比如YYYY/MM/DD HH:mm),需要在moment解析时指定对应格式,避免解析错误:moment(selectedDateElement.textContent, 'YYYY/MM/DD HH:mm')。 - 对于交互后必然出现的元素,优先使用
getByTestId而非queryByTestId,前者会自动等待元素渲染,减少测试不稳定的情况。
内容的提问来源于stack exchange,提问作者Milos
相关产品推荐
相关产品推荐

