我正在尝试为一个计时应用程序建模。
通常,当我有一个依赖时间的类时,我可以提供一个重载的构造函数或方法,以便能够将Clock注入该方法或类中并能够测试其行为。
如果我有一条命令需要能够将当前时间传递给事件,那么这在基于轴突的应用程序中如何发挥作用?
@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>
处理此问题的最佳方法是什么?命令应该只从上游花费时间吗?或者我可以注入时钟进行测试。
答案 0 :(得分:3)
在聚合(和其他轴突类型)中依赖时间时,可以使用GenericEventMessage.clock
,在大多数运行时配置中默认为System.UTC。
在测试期间,Testfixture将覆盖此时间为固定时间。更新Instant.now()的用法以使用此时钟。
@CommandHandler
public TimeCard(ClockInCommand cmd) {
AggregateLifecycle.apply(new ClockInEvent(cmd.getEmployeeName(), GenericEventMessage.clock.instant()));
}