有没有办法,无论是在代码中还是在JVM参数中,都可以覆盖当前时间,如System.currentTimeMillis手动更改主机上的系统时钟所示?
一点背景:
我们有一个系统可以运行许多会计工作,这些工作围绕当前日期(即本月的第一天,一年中的第一天等)展开大部分逻辑.
不幸的是,很多遗留代码都会调用诸如new Date()or之类的函数,这些函数Calendar.getInstance()最终都会调用System.currentTimeMillis.
出于测试目的,我们现在仍然需要手动更新系统时钟来操作代码认为运行测试的时间和日期.
所以我的问题是:
有没有办法覆盖返回的内容System.currentTimeMillis?例如,告诉JVM在从该方法返回之前自动添加或减去一些偏移量?
提前致谢!
我有service方法:
Entity entity = new Entity(new Date(), 1, 2L);
return entityRepository.save(entity);
Run Code Online (Sandbox Code Playgroud)
我的测试:
@Test
public void testSaveEntity() {
Entity entity = new Entity(new Date(), 1, 2L);
entityService.saveEntity(1, 2L);
verify(entityRepository, times(1)).save(entity);
}
Run Code Online (Sandbox Code Playgroud)
如果Entity equals()不进行比较Date,则一切正常,但如果进行比较Date,则测试会抛出Argument(s) are different!
在进行模拟调用之前自动更新时间戳的最佳方法是什么?
这是我试图测试的一些虚拟代码:
public class ThingWithATimestamp {
public Long timestamp;
public String name;
public ThingWithATimestamp(String name) {
this.name = name;
}
}
public class TheClassThatDoesStuff {
private ThingConnector connector;
public TheClassThatDoesStuff(ThingConnector connector) {
this.connector = connector;
}
public void updateTheThing(MyThingWithATimestamp thing) {
thing.timestamp = currentTimestamp();
connector.update(thing);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我想要测试的:
public class TheClassThatDoesStuffTests {
@Test
public void canUpdateTheThing() {
ThingConnector connector = mock(ThingConnector.class);
TheClassThatDoesStuff doer = new ThisClassThatDoesStuff(connector);
doer.updateTheThing(new ThingWithATimestamp("the name"));
verify(connector, times(1)).update(SomeMatcherThatICantFigureOut);
}
Run Code Online (Sandbox Code Playgroud)
我知道这段代码非常愚蠢,但我认为它准确地描绘了我想要验证的内容.我基本上需要一个匹配器来填写测试来验证时间戳是否在当前时间的X之内,所以我知道它已正确更新并且connector.update使用适当的时间戳为对象调用.