问题描述
我想模拟LocalDate.Now()
每次返回相同的日期。
为此,我尝试了两种不同的选择:
第一名:LocalDate.Now() >> LocalDate.of(2020,05,07)
第二:
def today = GroovyMock(LocalDate) {
getYear() >> 2020
getMonth() >> Month.APRIL
getDayOfMonth() >> 24
getDayOfWeek() >> DayOfWeek.FRIDAY
}
LocalDate.Now(timeZone) >> today
但这对我没有帮助,LocalDate.Now()
仍在调用代码时返回当前日期。每次返回模拟日期时如何实现LocalDate.Now()?
解决方法
不要。正是出于这个原因,Clock
类的存在正是出于 的原因。在被测类中,添加带有setter的属性:
private Clock clock = Clock.systemUTC();
并使用
LocalDate.now(clock)
在您的测试用例中,将默认的“真实时钟”替换为测试时钟:
subject.clock = Clock.fixed(specificInstant,UTC)
,
在Spock中无法使用内置工具来模拟Java类的静态方法。如果您确实想要-我同意您不赞成chrylis-您将需要使用其他工具,例如PowerMock或Sarek(我自己的一个宠物项目,仍未正式发布,但可在GitHub上使用)。
背景:顾名思义,Groovy模拟仅适用于Groovy类。将它们与Java类一起使用会使它们的行为类似于常规的Spock模拟,即,对静态方法进行存根无效。 here中对此进行了记录:
什么时候应该比常规的模仿更喜欢Groovy的模仿?当规范下的代码用Groovy 编写并且需要某些独特的Groovy模拟功能时,应使用Groovy模拟。 从Java代码调用时,Groovy模拟将表现得像普通模拟一样。请注意,仅因为规范和/或模拟类型下的代码是用Groovy编写的,所以不必使用Groovy模拟。除非您有具体的理由使用Groovy模拟,否则请选择常规模拟。