Время теста на Яве.Изменить значение заглушки спока - PullRequest
0 голосов
/ 11 декабря 2018

Я определил боб в моей весенней заявке.

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

Тогда в моем тесте я хочу заглушить этот боб.

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. Я ищу идеи, как изменить дизайн приложения.Моя цель -

    когда:

    // заглушка Clock с некоторым значением.

    // Делаем логику.Используйте часы несколько раз.

    // Изменить часы на другой экземпляр.

    // Делаем какую-то другую логику.Используйте часы несколько раз.

    затем:

    // Сделайте некоторое утверждение.(например, проверить разницу во времени)

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

Я придумаю решение, в котором я использую функцию, в которой я могу вычислить возвращаемое значение.

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
    }
}
0 голосов
/ 20 декабря 2018

Ты неправильно понял Спока.Вы можете объявить о взаимодействии только один раз для данного макета, заглушки или шпиона.Но что вы можете сделать, это объявить метод s tub, который возвращает последовательность значений .

Удаление беспорядка Spring (Boot) из вашего теста, просто используя обычный 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
  }
}
...