我知道你不能改变你需要测试的方法。不幸的是,这也意味着你坚持使用旧的,往往不是非常程序员友好的类(我假定java.util.Date
)。
编辑:您的方法使用的no-arg Date
构造函数反过来使用System.currentTimeMillis()
,这是一种静态本地方法。我不知道有些工具可以模拟构造函数和静态原生方法,但是被JMockit的开发人员@Rogério评论和answer告知,这种模拟工具存在。
在任何情况下,还存在另一种:你从今天开始计算天数部分,通过所产生的Date
的方法,并检查你回来,你在你的计算中使用的数量。这将在任何一天工作,不需要嘲弄/残留。
在下面的代码中,我假定getDaysUntil
方法应该放弃小时和分钟,并只看计算机时区中的日期。如果真实需求不同,您可以对我的代码进行适当的调整。
我们想要考虑到该方法可能会在午夜之后运行。如果是这样,我认为结果是未定义的,因为我们不知道Date
对象是在午夜之前还是之后构建的。在这种情况下,我只需再试一次,假设测试将在下一个午夜之前完成。
@Test
public void testGetDaysUntil() {
A instanceUnderTest = new A();
for (int daysToTest = 0; daysToTest <= 400; daysToTest++) {
LocalDate today;
int result;
do {
today = LocalDate.now(); // do this in each iteration in case day changes underway
LocalDate targetDate = today.plusDays(daysToTest);
Date midnightAtStartOfDay = Date.from(targetDate.atStartOfDay(ZoneId.systemDefault())
.toInstant());
result = instanceUnderTest.getDaysUntil(midnightAtStartOfDay);
} while (! today.equals(LocalDate.now())); // if we have passed midnight, try again
assertEquals(daysToTest, result);
do {
today = LocalDate.now();
LocalDate targetDate = today.plusDays(daysToTest);
Date nearMidnightAtEndOfDay = Date.from(targetDate.atTime(23, 59, 59, 400_000_000)
.atZone(ZoneId.systemDefault())
.toInstant());
result = instanceUnderTest.getDaysUntil(nearMidnightAtEndOfDay);
} while (! today.equals(LocalDate.now()));
assertEquals(daysToTest, result);
}
}
我已经使用Java 8类进行日期和时间计算。如果您不能使用Java 8,可以使用Calendar
和/或GregorianCalendar
,那么这项工作可能会稍微麻烦一点,但至少可以轻松转换为Date
。
是的,有很多方法可以做到这一点。一种可能的方式是在[我的答案]中描述(http://stackoverflow.com/q/11042200) –
@DavidWallace基本上所说的。并且请注意,自Java8以来,实际上有一个专门的类可以帮助您,称为java.time.Clock,因此您不必按链接答案中的建议滚动自己的实现。 –
它可能是我,但从@DavidWallace文章,我明白,我要改变原来的方法的代码。我不能那样做。 –