模拟ZoneDateTime Java8

模拟ZoneDateTime Java8,java,junit,junit5,Java,Junit,Junit5,我有一个模型构造函数,它生成一个时间戳作为 this.timestamp=null==timestamp?ZoneDateTime.now().toInstant().toEpochMilli():时间戳 如何模拟分区时间? 我需要使用测试用例验证时间戳的值是否为当前时间(以毫秒为单位) 由于它是一个模型,在构造函数中注入一个独立的时钟的依赖项是不可能的,我不希望更改源代码。这取决于你的类和你想做什么: 如果您想要模拟一个类的所有属性,而该类不是final,那么请使用类似于的模拟框架 如果您的

我有一个模型构造函数,它生成一个时间戳作为
this.timestamp=null==timestamp?ZoneDateTime.now().toInstant().toEpochMilli():时间戳

如何模拟分区时间? 我需要使用测试用例验证时间戳的值是否为当前时间(以毫秒为单位)


由于它是一个模型,在构造函数中注入一个独立的
时钟的依赖项是不可能的,我不希望更改源代码。

这取决于你的类和你想做什么:

  • 如果您想要模拟一个类的所有属性,而该类不是final,那么请使用类似于的模拟框架

  • 如果您的类是final,则只需模拟此单个属性,否则属性就是final:

  • 您可以创建一个静态工厂,它为您提供
    即时
    ,然后在测试中替换工厂

     class TimeFactory {
    
      private static Supplier<Instant>  INSTANT_SUPPLIER = Instant::now;
      public static Instant getInstant(){ return INSTANT_SUPPLIER.get(); }
      public static void setInstantSupplier(Supplier<Instant> new){ INSTANT_SUPPLIER= supplier; } 
    } 
    
    现在在测试中,您可以使用setter方法:

     TimeFactory.setInstantSupplier(()-> /*Your value*/ )
     // create your object
    
    只需记住在测试后返回默认供应商:

    TimeFactory.setInstantSupplier(Instant::now);
    
  • 如果您的属性不是final,那么添加一个包setter,它可以在您的测试中使用

  • 下一个解决方案(不推荐)是。但这不是模拟,而是使用强制设置私有(事件最终)属性

  • 还有一种方法


  • 1.为什么不直接使用
    Instant.now()
    而不是
    ZonedDateTime.now().toInstant()
    ?这将避免一个无用的步骤。2.您不能直接模拟
    ZoneDateTime.now()
    (或
    Instant.now()
    )。如果您想修改或模拟这样的功能,可以使用
    Clock
    对象,并使用任一类的
    now(Clock)
    方法,而不是参数较少的方法。时间戳值是否为最终值?是否要创建读取对象并仅设置此单个值,还是要模拟整个对象?在测试与时间相关的代码时,可能需要使用依赖项注入来使用模拟时钟。您不需要模拟框架。请看,已经有了一个专门的
    供应商
    接口,它是
    时钟
    (当然,它也提供时区信息。但这些都属于同一类)。很高兴知道,谢谢:)但供应商更多的是一个概念,为了了解一般的想法,如何覆盖供应商。学习如何像他们说的那样钓鱼。
     TimeFactory.setInstantSupplier(()-> /*Your value*/ )
     // create your object
    
    TimeFactory.setInstantSupplier(Instant::now);