代码之家  ›  专栏  ›  技术社区  ›  Luk

Java中的测试时间。更改spock存根值

  •  0
  • Luk  · 技术社区  · 7 年前

    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)
            }
        }
    
    }
    

    1. 我正在寻找如何重新设计应用程序的想法。我的目标是

      什么时候:

      //具有某些值的存根时钟。

      //做一些逻辑分析。使用时钟多次。

      //将时钟更改为另一个实例。

      //做一些其他的逻辑。使用时钟多次。

      然后:

      //做出一些断言。(例如检查时差)

    2 回复  |  直到 7 年前
        1
  •  2
  •   Luk    7 年前

    我提出了一个解决方案,在这个解决方案中,我使用了可以计算返回值的特性。

    http://spockframework.org/spock/docs/1.2/all_in_one.html#_computing_return_values

    在这里,我替换返回值。

    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
        }
    }
    
        2
  •  1
  •   kriegaex    7 年前

    你误解了斯波克。对于给定的mock、stub或spy,只能声明一次交互。但是你能做的是声明一个tub方法来返回一个 sequence of values

    从测试中删除Spring(启动)混乱,只需使用普通Spock,如下所示:

    package de.scrum_master.stackoverflow
    
    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
      }
    }