Как я могу проверить агрегат, который полагается на время? - PullRequest
1 голос
/ 02 февраля 2020

Я пытаюсь смоделировать приложение для хранения времени.

Обычно, когда у меня есть класс, зависящий от времени, я могу предоставить перегруженный конструктор или метод, чтобы иметь возможность вводить часы в этот метод или класс и быть в состоянии проверить его поведение.

Если у меня есть команда, которая должна иметь возможность передавать текущее время в событие, как это может работать в совокупности приложения, основанного на аксонах?

@Aggregate
@Slf4j
public class TimeCard {

  @AggregateIdentifier
  private String employeeName;
  private Instant clockInTime;

  public TimeCard() {
    //Axon requires empty constructor on aggregate
  }

  @CommandHandler
  public TimeCard(ClockInCommand cmd) {
    AggregateLifecycle.apply(new ClockInEvent(cmd.getEmployeeName(), Instant.now()));
  }

  @EventSourcingHandler
  public void on(ClockInEvent event) {
    this.employeeName = event.getEmployeeName();
    this.clockInTime = event.getClockInTime();
  }
}

Казалось, что испытательный прибор справился с этим чисто для меня, предоставив методы, обеспечивающие время. Вот мой метод тестирования:

@Test
void testClockInCommand() {
  testFixture.givenNoPriorActivity()
    .andGivenCurrentTime(clock.instant())
    .when(new ClockInCommand("GoldFlsh"))
    .expectEvents(new ClockInEvent("GoldFlsh", testFixture.currentTime()));
}

Но мое событие в конечном итоге отличалось на долю секунды.

Expected <2020-02-02T13:47:20.684344700Z> but got <2020-02-02T13:47:20.954347700Z>

Какой лучший способ справиться с этим? Должны ли команды занимать время только в восходящем направлении? Или я могу как-то ввести часы для тестирования.

1 Ответ

3 голосов
/ 02 февраля 2020

Если вы полагаетесь на время в Aggregates (и других типах аксонов), вы можете использовать GenericEventMessage.clock, который по умолчанию равен System.UT C в большинстве конфигураций времени выполнения.

Testfixture переопределит это, чтобы быть фиксированное время во время испытаний. Обновите использование Instant.now (), чтобы использовать эти часы.

@CommandHandler
public TimeCard(ClockInCommand cmd) {
  AggregateLifecycle.apply(new ClockInEvent(cmd.getEmployeeName(), GenericEventMessage.clock.instant()));
}
...