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

huangapple go评论70阅读模式
英文:

How to mock static method in LocalDate using Spock?

问题

我想要模拟 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() 每次都返回模拟的日期呢?

英文:

I wanna mock LocalDate.now() to return each time the same date.

For this I tried two different options:

First : LocalDate.now() >> LocalDate.of(2020, 05, 07)

Second:

def today = GroovyMock(LocalDate) {
                  getYear() >> 2020
                  getMonth() >> Month.APRIL
                  getDayOfMonth() >> 24
                  getDayOfWeek() >> DayOfWeek.FRIDAY
                }
    LocalDate.now(timeZone) >> today

But it does not help me, LocalDate.now() still return the current date when it calls in the code. How I can achieve that LocalDate.now() every time return me the mock date?

答案1

得分: 2

不要。Clock类存在的目的就是完全为了这个原因。在被测试的类中,添加一个带有setter的属性:

private Clock clock = Clock.systemUTC();

并且使用:

LocalDate.now(clock)

在你的测试用例中,用一个测试用的时钟替换默认的“真实时钟”:

subject.clock = Clock.fixed(specificInstant, UTC)
英文:

Don't. The Clock class exists for exactly this reason. In the class under test, add a property with a setter:

private Clock clock = Clock.systemUTC();

and use

LocalDate.now(clock)

In your test case, replace the default "real clock" with a test clock:

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

答案2

得分: 0

在 Spock 中,使用内置工具无法模拟 Java 类的静态方法。如果您真的想要这样做 - 我同意 chrylis 的观点,您将需要使用其他工具,比如 PowerMock 或 Sarek(这是我自己的一个宠物项目,尚未正式发布,但在 GitHub 上可用)。

背景:正如名称所示,Groovy 模拟仅适用于 Groovy 类。将它们用于 Java 类会使它们的行为类似于常规的 Spock 模拟,即对静态方法进行存根操作没有效果。这在文档中有说明(http://spockframework.org/spock/docs/1.3/all_in_one.html#GroovyMocks):

> 何时应优先选择 Groovy Mocks 而不是常规 Mocks?只有在要规范化的代码是用 Groovy 编写的 并且 需要一些独特的 Groovy 模拟特性时,才应使用 Groovy 模拟。从 Java 代码调用时,Groovy 模拟将表现得像常规模拟。 请注意,仅因为要规范化的代码和/或模拟类型是用 Groovy 编写的,并不一定需要使用 Groovy 模拟。除非您有明确的理由使用 Groovy 模拟,否则请使用常规模拟。

英文:

There is no way to mock static methods of Java classes in Spock using on-board tools. If you really want that - and I agree with chrylis that you don't - you would need to use an addititonal tool such as PowerMock or Sarek (one of my own pet projects, still not officially released, but available on GitHub).

Background: Groovy mocks, as the name implies, only work with Groovy classes. Using them with Java classes makes them behave like regular Spock mocks, i.e. stubbing static methods has no effect. this is documented 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.

huangapple
  • 本文由 发表于 2020年8月31日 23:31:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/63673756.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定