java - 覆盖 Java System.currentTimeMillis 以测试时间敏感代码

标签 java testing jvm systemtime

有没有办法,无论是在代码中还是使用 JVM 参数,都可以覆盖当前时间,如 System.currentTimeMillis 所示,除了手动更改主机上的系统时钟?

一点背景:

我们有一个系统运行许多会计作业,这些作业的大部分逻辑都围绕当前日期(即本月 1 日、一年 1 日等)

不幸的是,许多遗留代码调用函数,例如 new Date()Calendar.getInstance() , 两者最终都调用到 System.currentTimeMillis .

出于测试目的,目前,我们只能手动更新系统时钟来控制代码认为正在运行测试的时间和日期。

所以我的问题是:

有没有办法覆盖 System.currentTimeMillis 返回的内容?例如,告诉 JVM 在从该方法返回之前自动添加或减去一些偏移量?

最佳答案

强烈建议不要弄乱系统时钟,而是硬着头皮重构旧代码以使用可替换时钟。 理想情况下应该通过依赖注入(inject)来完成,但即使您使用可替换的单例,您也可以获得可测试性。

这几乎可以通过单例版本的搜索和替换实现自动化:

  • Calendar.getInstance() 替换为 Clock.getInstance().getCalendarInstance()
  • new Date() 替换为 Clock.getInstance().newDate()
  • System.currentTimeMillis() 替换为 Clock.getInstance().currentTimeMillis()

(根据需要等)

一旦您迈出了第一步,您就可以一次用 DI 替换单例。

关于java - 覆盖 Java System.currentTimeMillis 以测试时间敏感代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2001671/

相关文章:

java 选项内存不足时堆转储

java - 当服务触发操作时如何通知 Activity

在 TreeView 中拖动项目时,JavaFX OnMouseDragged 不会被触发

testing - 是否可以在没有父/子链接的情况下在测试计划中获取工作项树?

java - 如何在 Windows 上区分两个正在运行的 java 进程?

java - 加载类总数不断增加

java - awk 完整的 C/C++/Java 函数

java - 获取枚举类型变量的注释

python - Django 中 assertDatabaseHas 的等价物是什么

angularjs - 如何测试 Angular 装饰器功能