I am new to Axon framework and am trying to implement an application using CQRS with state-stored aggregates. The aggregate is created via a command handling constructor that assigns a random UUID as the aggregate identifier.
To test commands on the aggregate, I create the aggregate via a givenCommands(new CreatePlanCommand(...) call. I then want to issue the command under test, UpdatePlanNameCommand in this case, but that command needs the aggregate id that was assigned by the CreatePlanCommand executed in the test setup. Is there a way to retrieve this?
Example test code shown below (see question in comment on when() call):
@Test
public void plan_updatePlan_updatesPlanName() {
testFixture
.givenCommands(new CreatePlanCommand(123L, "My Test Plan", funds))
.when(new UpdatePlanNameCommand(/* How to get aggregate id returned by CreatePlanCommand here? */, "New Name"))
.expectSuccessfulHandlerExecution()
.expectState(state -> {
assertThat(state.getCompanyId(), equalTo(123L));
assertThat(state.getName(), equalTo("New Name"));
assertThat(state.getAvailableFunds(), equalTo(funds));
});
}
The command handler that creates the plan is as follows:
@CommandHandler
public Plan(CreatePlanCommand command, PlanFundValidator planFundValidator) {
// Use injected domain service to verify that all funds in this plan's lineup actually exist
planFundValidator.validateFundsExist(command.getAvailableFunds());
this.id = UUID.randomUUID();
this.companyId = command.getCompanyId();
this.name = command.getName();
this.availableFunds = new HashSet<>(command.getAvailableFunds());
apply(planCreatedEvent());
}
Update: I was able to get the test working by using .givenState(...) to create the aggregate as follows:
@Test
public void plan_updatePlan_updatesPlanName() {
AtomicReference<UUID> planId = new AtomicReference<>();
testFixture
.givenState(() -> {
Plan plan = new Plan(new CreatePlanCommand(123L, "My Test Plan", funds), mockPlanFundValidator);
planId.set(plan.getId());
return plan;
})
.when(new UpdatePlanNameCommand(planId.get(), "New Name"))
.expectSuccessfulHandlerExecution()
.expectState(state -> {
assertThat(state.getCompanyId(), equalTo(123L));
assertThat(state.getName(), equalTo("New Name"));
assertThat(state.getAvailableFunds(), equalTo(funds));
});
}
but this seems overly verbose and a step backwards in terms of test readability and maintenance, so I am still curious if there is a way to accomplish this with .givenCommands(...). Thank you.