我正在使用 Groovy 和 Spock 框架设置测试。我的测试取决于时间的流逝,并且相关服务使用 new Date() 来执行某些规则。因此,我想在测试中修改 new Date(),例如返回未来 7 天的日期。
我尝试过使用
metaClass
、Mockito
和 PowerMockito
等,但这些场景似乎都不起作用,因为我们似乎无法模拟静态方法或本机方法。这种情况有什么解决办法吗?
我强烈建议您使用
java.time.*
api,而不是依赖遗留的 java.util.Date
类。
然后你可以简单地注入一个自定义的java.time.Clock
来模拟时间,就像Spock的MutableClock。
public class AgeFilter implements Predicate<LocalDate> {
private final Clock clock;
private final int age;
public AgeFilter(Clock clock, int age) {
this.clock = clock;
this.age = age;
}
@Override
public boolean test(LocalDate date) {
return Period.between(date, LocalDate.now(clock)).getYears() >= age;
}
}
def "AgeFilter reacts to time"() {
given:
ZonedDateTime defaultTime = ZonedDateTime.of(2018, 6, 5, 0, 0, 0, 0, ZoneId.of('UTC'))
MutableClock clock = new MutableClock(defaultTime)
AgeFilter ageFilter = new AgeFilter(clock,18)
LocalDate birthday = defaultTime.minusYears(18).plusDays(1).toLocalDate()
expect:
!ageFilter.test(birthday)
when:
clock + Duration.ofDays(1)
then:
ageFilter.test(birthday)
}