如何使用 Spock 在 LocalDate 中模拟静态方法?

How to mock static method in LocalDate using Spock?

我想每次都在同一日期模拟 LocalDate.now() 到 return。

为此我尝试了两种不同的选择:

第一个: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() 仍然是 return 它在代码中调用时的当前日期。每次 return 模拟约会时,我如何实现 LocalDate.now()?

不要。 Clock class 的存在正是因为 这个原因。在测试的 class 中,添加一个 属性 和一个 setter:

private Clock clock = Clock.systemUTC();

并使用

LocalDate.now(clock)

在您的测试用例中,将默认的“真实时钟”替换为测试时钟:

subject.clock = Clock.fixed(specificInstant, UTC)

无法使用 on-board 工具在 Spock 中模拟 Java 类 的静态方法。如果你真的想要那个——我同意你不想要的 chrylis 的观点——你需要使用一个额外的工具,比如 PowerMock 或 Sarek(我自己的宠物项目之一,仍然没有正式发布,但可以在 GitHub).

背景:Groovy 模拟,顾名思义,仅适用于 Groovy 类。将它们与 Java 类 一起使用会使它们表现得像常规的 Spock 模拟,即存根静态方法没有效果。这是记录在案 here:

When Should Groovy Mocks be Favored over Regular Mocks? Groovy mocks should be used when the code under specification is written in Groovy and some of the unique Groovy mock features are needed. When called from Java code, Groovy mocks will behave like regular mocks. Note that it isn’t necessary to use a Groovy mock merely because the code under specification and/or mocked type is written in Groovy. Unless you have a concrete reason to use a Groovy mock, prefer a regular mock.