我最近在学习 CQRS,所以我开始了一个带有 axon-framework(一个 java CRQS 框架)的示例项目。
根据快速入门,我得到了以下信息:
public class CreditEntryUnitTests {
private FixtureConfiguration fixture;
@Before
public void setUp() throws Exception {
fixture = Fixtures.newGivenWhenThenFixture(CreditEntry.class);
}
@Test
public void creditEntryCreated() throws Throwable {
final Long entryId = 1L;
final int amount = 100;
fixture.given().when(new CreateCreditEntryCommand(entryId, amount))
.expectEvents(new CreditEntryCreatedEvent(entryId, amount));
}
@Test
public void creditEntryMadeEffective() throws Throwable {
final Long entryId = 1L;
final int amount = 100;
final Date start = nov(2011, 12);
final Date end = nov(2012, 12);// a year effective period
fixture.given(new CreditEntryCreatedEvent(entryId, amount))
.when(new MakeCreditEntryEffectiveCommand(entryId, start, end))
.expectEvents(new CreditEntryMadeEffectiveEvent(entryId, start, end));
}
//omitted support methods
}
public class CreditEntry extends AbstractAnnotatedAggregateRoot {
@AggregateIdentifier
private Long id;
private int amount;
private Date effectiveDateRangeStart;
private Date effectiveDateRangeEnd;
private Status status;
@CommandHandler
public CreditEntry(CreateCreditEntryCommand command) {
apply(new CreditEntryCreatedEvent(
command.getEntryId(), command.getAmount()));
}
@EventHandler
public void on(CreditEntryCreatedEvent event) {
this.id = event.getEntryId();
this.amount = event.getAmount();
this.status = Status.NEW;
}
@CommandHandler
public void markCompleted(MakeCreditEntryEffectiveCommand command) {
apply(new CreditEntryMadeEffectiveEvent(
command.getEntryId(), command.getStart(), command.getEnd()));
}
@EventHandler
public void on(CreditEntryMadeEffectiveEvent event) {
this.effectiveDateRangeStart = event.getStart();
this.effectiveDateRangeEnd = event.getEnd();
this.status = Status.EFFECTIVE;
}
public CreditEntry() {}
public enum Status {
NEW, EFFECTIVE, EXPIRED
}
}
测试代码促使我使用 axon-framework 编写域模型和集成代码,但它没有涵盖事件产生的副作用。我在哪里测试它们?例如,当信用分录生效时,它的状态应该是有效的。我是否应该在其他测试方法中创建 CreditEntry 实例并通过调用特定的 on(...Event event) 方法进行测试?
还有一个问题是:我应该把业务验证逻辑放在哪里?在命令处理程序方法中?假设如果 CreditEntry 已经生效,则不能再次生效。
@CommandHandler
public void markCompleted(MakeCreditEntryEffectiveCommand command) {
if (is(NEW)) {
apply(new CreditEntryMadeEffectiveEvent(
command.getEntryId(), command.getStart(), command.getEnd()));
} else {
throw new IllegalStateException(.......);
}
}
任何想法都值得赞赏,谢谢。