测试时间在 Java。更改 spock 存根值
Test time in Java. Change spock stub value
我已经在我的 spring 应用程序中定义了 bean。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Clock;
@Configuration
public class ClockConfiguration {
@Bean
Clock getSystemDefaultZoneClock() {
return Clock.systemDefaultZone();
}
}
然后在我的测试中我想存根这个bean。
import io.github.jhipster.config.JHipsterConstants
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.TestConfiguration
import org.springframework.context.annotation.Bean
import org.springframework.test.context.ActiveProfiles
import spock.lang.Specification
import spock.mock.DetachedMockFactory
import java.time.Clock
import java.time.Instant
import java.time.LocalDateTime
import static java.time.ZoneId.systemDefault
@ActiveProfiles(profiles = JHipsterConstants.SPRING_PROFILE_TEST)
@EnableConfigurationProperties
@SpringBootTest(classes = [MyApp])
class ClockTest extends Specification {
@Autowired
Clock clock
//2018-04-01 at 10:00am
private static Instant REFERENCE_DATE_TIME = LocalDateTime.of(2018, 4, 1, 10, 0)
.atZone(systemDefault())
.toInstant()
//2018-04-01 at 10:00am
private static Instant OTHER_REFERENCE_DATE_TIME = LocalDateTime.of(2018, 4, 2, 10, 0)
.atZone(systemDefault())
.toInstant()
def "should return different date"() {
when:
clock.instant() >> REFERENCE_DATE_TIME
then:
clock.instant() == REFERENCE_DATE_TIME
when:
clock.instant() >> OTHER_REFERENCE_DATE_TIME
then:
clock.instant() == OTHER_REFERENCE_DATE_TIME
}
@TestConfiguration
static class Mocks {
def detachedMockFactory = new DetachedMockFactory()
@Bean
Clock clock() {
return detachedMockFactory.Stub(Clock)
}
}
}
由于第二个断言,此测试失败。我的 stubed bean returns 值由第一次交互声明。
- 我想明白为什么这个交互没有改变。
我正在寻找如何重新设计应用程序的想法。我的目标是
时间:
//具有某些值的存根时钟。
//做一些逻辑。多次使用时钟。
//将时钟更改为另一个实例。
//做一些其他的逻辑。多次使用时钟。
然后:
//做一些断言。 (例如检查时差)
你误会了 Spock。您只能在给定的模拟、存根或间谍中声明一次交互。但是你可以做什么它声明 s tub 方法到 return a sequence of values.
从您的测试中移除 Spring(引导)混乱,仅使用普通的 Spock,它看起来像这样:
package de.scrum_master.Whosebug
import spock.lang.Specification
import java.time.Clock
import java.time.Instant
import java.time.LocalDateTime
import static java.time.ZoneId.systemDefault
class ClockStubTest extends Specification {
private static Instant REFERENCE_DATE_TIME = LocalDateTime.of(2018, 4, 1, 10, 0)
.atZone(systemDefault())
.toInstant()
private static Instant OTHER_REFERENCE_DATE_TIME = LocalDateTime.of(2018, 4, 2, 10, 0)
.atZone(systemDefault())
.toInstant()
Clock clock = Stub()
def "should return different date"() {
given:
clock.instant() >>> [REFERENCE_DATE_TIME, OTHER_REFERENCE_DATE_TIME]
expect:
clock.instant() == REFERENCE_DATE_TIME
clock.instant() == OTHER_REFERENCE_DATE_TIME
}
}
或者您也可以直接在创建的存根范围内声明存根方法:
// (...)
Clock clock = Stub() {
instant() >>> [REFERENCE_DATE_TIME, OTHER_REFERENCE_DATE_TIME]
}
def "should return different date"() {
expect:
clock.instant() == REFERENCE_DATE_TIME
clock.instant() == OTHER_REFERENCE_DATE_TIME
}
}
我想出了一个解决方案,我正在使用可以计算 return 值的功能。
http://spockframework.org/spock/docs/1.2/all_in_one.html#_computing_return_values
并在其中替换 returned 值。
import spock.lang.Specification
import java.time.Clock
import java.time.Instant
import java.time.LocalDateTime
import static java.time.ZoneId.systemDefault
class ClockStubTest extends Specification {
private static Instant REFERENCE_DATE_TIME = LocalDateTime.of(2018, 4, 1, 10, 0)
.atZone(systemDefault())
.toInstant()
private static Instant OTHER_REFERENCE_DATE_TIME = LocalDateTime.of(2018, 4, 2, 10, 0)
.atZone(systemDefault())
.toInstant()
Clock clock = Stub()
def "should return different date"() {
given:
def now
clock.instant() >> { now }
when:
now = REFERENCE_DATE_TIME
then:
clock.instant() == REFERENCE_DATE_TIME
clock.instant() == REFERENCE_DATE_TIME
when:
now = OTHER_REFERENCE_DATE_TIME
then:
clock.instant() == OTHER_REFERENCE_DATE_TIME
clock.instant() == OTHER_REFERENCE_DATE_TIME
clock.instant() == OTHER_REFERENCE_DATE_TIME
}
}
我已经在我的 spring 应用程序中定义了 bean。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Clock;
@Configuration
public class ClockConfiguration {
@Bean
Clock getSystemDefaultZoneClock() {
return Clock.systemDefaultZone();
}
}
然后在我的测试中我想存根这个bean。
import io.github.jhipster.config.JHipsterConstants
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.TestConfiguration
import org.springframework.context.annotation.Bean
import org.springframework.test.context.ActiveProfiles
import spock.lang.Specification
import spock.mock.DetachedMockFactory
import java.time.Clock
import java.time.Instant
import java.time.LocalDateTime
import static java.time.ZoneId.systemDefault
@ActiveProfiles(profiles = JHipsterConstants.SPRING_PROFILE_TEST)
@EnableConfigurationProperties
@SpringBootTest(classes = [MyApp])
class ClockTest extends Specification {
@Autowired
Clock clock
//2018-04-01 at 10:00am
private static Instant REFERENCE_DATE_TIME = LocalDateTime.of(2018, 4, 1, 10, 0)
.atZone(systemDefault())
.toInstant()
//2018-04-01 at 10:00am
private static Instant OTHER_REFERENCE_DATE_TIME = LocalDateTime.of(2018, 4, 2, 10, 0)
.atZone(systemDefault())
.toInstant()
def "should return different date"() {
when:
clock.instant() >> REFERENCE_DATE_TIME
then:
clock.instant() == REFERENCE_DATE_TIME
when:
clock.instant() >> OTHER_REFERENCE_DATE_TIME
then:
clock.instant() == OTHER_REFERENCE_DATE_TIME
}
@TestConfiguration
static class Mocks {
def detachedMockFactory = new DetachedMockFactory()
@Bean
Clock clock() {
return detachedMockFactory.Stub(Clock)
}
}
}
由于第二个断言,此测试失败。我的 stubed bean returns 值由第一次交互声明。
- 我想明白为什么这个交互没有改变。
我正在寻找如何重新设计应用程序的想法。我的目标是
时间:
//具有某些值的存根时钟。
//做一些逻辑。多次使用时钟。
//将时钟更改为另一个实例。
//做一些其他的逻辑。多次使用时钟。
然后:
//做一些断言。 (例如检查时差)
你误会了 Spock。您只能在给定的模拟、存根或间谍中声明一次交互。但是你可以做什么它声明 s tub 方法到 return a sequence of values.
从您的测试中移除 Spring(引导)混乱,仅使用普通的 Spock,它看起来像这样:
package de.scrum_master.Whosebug
import spock.lang.Specification
import java.time.Clock
import java.time.Instant
import java.time.LocalDateTime
import static java.time.ZoneId.systemDefault
class ClockStubTest extends Specification {
private static Instant REFERENCE_DATE_TIME = LocalDateTime.of(2018, 4, 1, 10, 0)
.atZone(systemDefault())
.toInstant()
private static Instant OTHER_REFERENCE_DATE_TIME = LocalDateTime.of(2018, 4, 2, 10, 0)
.atZone(systemDefault())
.toInstant()
Clock clock = Stub()
def "should return different date"() {
given:
clock.instant() >>> [REFERENCE_DATE_TIME, OTHER_REFERENCE_DATE_TIME]
expect:
clock.instant() == REFERENCE_DATE_TIME
clock.instant() == OTHER_REFERENCE_DATE_TIME
}
}
或者您也可以直接在创建的存根范围内声明存根方法:
// (...)
Clock clock = Stub() {
instant() >>> [REFERENCE_DATE_TIME, OTHER_REFERENCE_DATE_TIME]
}
def "should return different date"() {
expect:
clock.instant() == REFERENCE_DATE_TIME
clock.instant() == OTHER_REFERENCE_DATE_TIME
}
}
我想出了一个解决方案,我正在使用可以计算 return 值的功能。
http://spockframework.org/spock/docs/1.2/all_in_one.html#_computing_return_values
并在其中替换 returned 值。
import spock.lang.Specification
import java.time.Clock
import java.time.Instant
import java.time.LocalDateTime
import static java.time.ZoneId.systemDefault
class ClockStubTest extends Specification {
private static Instant REFERENCE_DATE_TIME = LocalDateTime.of(2018, 4, 1, 10, 0)
.atZone(systemDefault())
.toInstant()
private static Instant OTHER_REFERENCE_DATE_TIME = LocalDateTime.of(2018, 4, 2, 10, 0)
.atZone(systemDefault())
.toInstant()
Clock clock = Stub()
def "should return different date"() {
given:
def now
clock.instant() >> { now }
when:
now = REFERENCE_DATE_TIME
then:
clock.instant() == REFERENCE_DATE_TIME
clock.instant() == REFERENCE_DATE_TIME
when:
now = OTHER_REFERENCE_DATE_TIME
then:
clock.instant() == OTHER_REFERENCE_DATE_TIME
clock.instant() == OTHER_REFERENCE_DATE_TIME
clock.instant() == OTHER_REFERENCE_DATE_TIME
}
}