java - 如何测试依赖时间的聚合?
问题描述
我正在尝试为计时应用程序建模。
通常,当我有一个依赖于时间的类时,我可以提供一个重载的构造函数或方法,以便能够将 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>
处理这个问题的最佳方法是什么?命令是否应该只从上游获取时间?或者我可以以某种方式注入时钟进行测试。
解决方案
在聚合(和其他轴突类型)中依赖时间时,您可以GenericEventMessage.clock
在大多数运行时配置中使用默认为 System.UTC 的。
Testfixture 将在测试期间将其覆盖为固定时间。更新 Instant.now() 的使用以使用此时钟。
@CommandHandler
public TimeCard(ClockInCommand cmd) {
AggregateLifecycle.apply(new ClockInEvent(cmd.getEmployeeName(), GenericEventMessage.clock.instant()));
}
推荐阅读
- composer-php - 如何在 Plesk Obsidian 中使用 Composer 安装 mPDF
- reactjs - React-sortble-tree:如何根据当前节点找到父节点:getNodeAtPath-way-of-working?
- c# - 在 .Net 标准项目中使用 Microsoft.AspNetCore.Identity?
- java - TextField 的输入值等于数组列表值,但不会上报该值。为什么?
- angular - 如何替换以前选择的文件?
- sql - 不能在一个 .bat 文件中运行两个 .sql
- ios - 使用 Xcode 11 启用 Bitcode 的 iOS 框架
- python-3.x - 尝试拆分字符串,但我遇到了与编码相关的问题
- .net-core - MQ PubSub - 如何从 .Net 读取 IBM MQ PubSub 的示例
- c# - 从 AJAX 将整数数组发送到 selectpicker 值