使用React Testing Library测试Luxon Datetime调用函数时报错
问题:React Testing Library测试时出现
endTime.diff is not a function错误 基于React(17.0.26)、React Hook Form(7.22.5)和Luxon(2.3.1)开发的表单组件核心代码如下:
const CreateAppointmentForm = () =>{ const currentDate = DateTime.now(); const form = useForm<FormSchema>({ resolver: (values, ...rest) => formSchema(values as FormSchema, ...rest), defaultValues: { endTime: currentDate.plus({ minute: 15 }), startTime: currentDate, }, }); const starTime = watch('startTime'); const endTime = watch('endTime'); const duration = endTime.diff(starTime, 'minutes').minutes; return <div>{duration}</div> }
使用React Testing Library测试组件时,抛出错误:Error: Uncaught [TypeError: endTime.diff is not a function],日志显示对象是有效的datetime结构,但缺少Luxon实例的方法。技术栈包含Typescript,Node版本16.16.0。
解决方案
- 根本原因:React Hook Form在处理表单值时,会对默认值进行序列化/反序列化操作,导致Luxon的
DateTime实例失去原型链上的方法,退化为普通JavaScript对象。 - 修复方法:
- 手动转换实例:在获取watch返回的值后,重新转换为Luxon DateTime实例:
const starTime = DateTime.fromJSObject(watch('startTime')); const endTime = DateTime.fromJSObject(watch('endTime')); const duration = endTime.diff(starTime, 'minutes').minutes; - 全局配置类型转换:在
useForm初始化时,通过setValueAs配置自动处理类型转换,确保所有表单值始终保持为DateTime实例:const form = useForm<FormSchema>({ resolver: (values, ...rest) => formSchema(values as FormSchema, ...rest), defaultValues: { startTime: currentDate, endTime: currentDate.plus({ minute: 15 }), }, setValueAs: (value) => { if (value instanceof DateTime) return value; return DateTime.fromJSObject(value); }, }); - 测试环境适配:如果测试用例中仍出现问题,确保测试时传入的默认值是完整的DateTime实例,或者在测试前模拟React Hook Form的序列化逻辑,避免实例被拆解为普通对象。
- 手动转换实例:在获取watch返回的值后,重新转换为Luxon DateTime实例:
内容的提问来源于stack exchange,提问作者Diogo Silva
相关产品推荐
相关产品推荐

