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

使用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对象。
  • 修复方法:
    1. 手动转换实例:在获取watch返回的值后,重新转换为Luxon DateTime实例:
      const starTime = DateTime.fromJSObject(watch('startTime'));
      const endTime = DateTime.fromJSObject(watch('endTime'));
      const duration = endTime.diff(starTime, 'minutes').minutes;
      
    2. 全局配置类型转换:在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);
        },
      });
      
    3. 测试环境适配:如果测试用例中仍出现问题,确保测试时传入的默认值是完整的DateTime实例,或者在测试前模拟React Hook Form的序列化逻辑,避免实例被拆解为普通对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 14:52:59