Java 在JUnit测试夹具中设置时间和日期

Java 在JUnit测试夹具中设置时间和日期,java,junit,Java,Junit,作为Java代码的一部分,一些任务明天需要在JUnit中完成 例如,有3项任务: 任务1-完成 任务2-明天做 任务3-那么这将发生 因此,根据要求,我需要在Java中将今天的日期设置为明天。关键是提取“可以为您提供当前时间的内容”作为依赖项。(以及相关时区。) 因此,您使用的不是newdate()或System.currentTimeMillis()而是Clock抽象。对于生产代码,您注入一个使用底层系统时钟的实例,但是对于测试,您使用一个可以显式控制的假时钟,使其返回您想要的任何内容 (

作为Java代码的一部分,一些任务明天需要在JUnit中完成

例如,有3项任务:

  • 任务1-完成
  • 任务2-明天做
  • 任务3-那么这将发生

因此,根据要求,我需要在Java中将今天的日期设置为明天。

关键是提取“可以为您提供当前时间的内容”作为依赖项。(以及相关时区。)

因此,您使用的不是
newdate()
System.currentTimeMillis()
而是
Clock
抽象。对于生产代码,您注入一个使用底层系统时钟的实例,但是对于测试,您使用一个可以显式控制的假时钟,使其返回您想要的任何内容


(老实说,你到底想达到什么目的还不清楚,但这种方法是我使时间可测试的标准方法。)

问题的根源在于系统时钟(在
新日期()
中为你提供时间的时钟)没有给你测试所需的时间

您可以通过引入间接级别来避免此问题。与其让代码直接询问Java API当前时间是多少,不如让代码询问
时钟
对象当前时间是多少。在实际程序中,您的
时钟
实现使用系统时钟。对于您的单元测试,您使用了一个
假时钟
,它可以显示您希望它显示的任何时间。您可以使用依赖项注入告诉代码要使用的
时钟。您必须自己编写
时钟
接口(或抽象基类)及其具体实现

这种方法要求您修改现有代码,以便更容易测试。或者在第一个地方写它,这样更容易测试。这是单元测试的技巧之一

我正在编写一些对时间敏感的代码。我的时钟接口很简单

 public interface Clock {
    long getCurrentTime ();
 }

考虑GitHub上的以下代码:&&
DateSupplier
有一个返回当前日期的静态方法
DateController
允许您在测试环境中操作
DateSupplier
返回的日期值。这是一条
JUnit规则
,并在其自身之后进行清理

这是另两个答案中
时钟
思想的具体实现。我已经在我的项目中使用了一年左右,取得了很好的成功。每当我有代码执行
new Date()
时,我就会调用
DateSupplier.getCurrentDate()

考虑使用,它是Java日期和时间类的替代品。它提供

DateTimeUtils.setCurrentMillisFixed(long millis);

可以在您的测试中使用。

您能告诉我们您的单元测试的来源吗?我不需要使用任何框架。我在每个任务之后只有3个任务,比如3个方法调用。f1()->f2()->f3()。f2可以在明天完成,然后在结果中调用f3。另请参见+1。我已经建立了一个限时试用版,并一直看到Joda time在《关于时间的回答》中。这是一个值得改成Joda Time的问题。我花了不到一个小时的时间安装它,更改代码以使用它,并根据此建议设置测试。调用应该是
DateTimeUtils.setCurrentMillisFixed(…)
。这是设置特定日期时间的调用
DateTimeUtils.setCurrentMillisSystem()
(无参数)设置DateTime以使用当前系统时间。看,很好,我喜欢这个。