在JUnit测试夹具中设置时间和日期
作为Java代码的一部分,明天需要在JUnit中完成一些任务。
例如,有3个任务:
- task1 – 完成
- task2 – 明天再做
- task3 – 然后就会发生这种情况
因此,根据要求,我需要在Java中将今天的日期设置为明天。
问题的根源在于系统时钟(在new Date ()
给你时间的东西)没有给你测试所需的时间。
您可以通过引入一个间接级别来避免此问题。 您没有让代码直接询问Java API当前时间,而是让您的代码向Clock
对象询问时间。 在实际程序中,您的Clock
实现使用系统时钟。 对于您的unit testing,您使用FakeClock
,它表示您想要的任何时间。 您告诉您的代码使用dependency injection时使用什么Clock
。 您必须自己编写Clock
接口(或抽象基类)及其具体实现。
这种方法要求您更改现有代码,因此更容易测试或首先编写它,以便更容易测试。 这是unit testing的技巧之一。
我正在研究一些对时间敏感的代码。 我的时钟界面很简单
public interface Clock { long getCurrentTime (); }
关键是要提取“可以给你当前时间的东西”的想法作为依赖。 (连同相关时区。)
因此,不使用new Date()
或System.currentTimeMillis()
而是使用Clock
抽象。 对于生产代码,您注入了一个使用底层系统时钟的实例,但是为了测试,您可以使用可以显式控制的假时钟,使其返回您想要的任何内容。
(说实话,我真的不清楚你要实现的目标,但这种方法是我时间可测试的标准方法。)
考虑GitHub上的以下代码: DateSupplier && DateController 。 DateSupplier
有一个返回当前日期的静态方法。 DateController
允许您操作DateSupplier
在测试环境中返回的日期值。 这是一个JUnit Rule
并在它自己清理之后。
这是来自其他两个答案的Clock
想法的具体实现。 我已经在我的项目中使用了一年左右并取得了很好的成功。 每当我有代码可以执行new Date()
我会调用DateSupplier.getCurrentDate()
代替。
考虑使用Joda Time ,它是Java日期和时间类的替代品。 它提供
DateTimeUtils.setCurrentMillisFixed(long millis);
可以在您的测试中使用。