How to test external command handlers?

Hi,
As documented we have AggregateTestFixture to help test aggregate command handlers, but there isn’t any document about testing external command handlers. Any suggestions?
Thanks.

And another question is AggregateTestFixture only for event sourcing aggregate?
It seems it uses eventsourcing.EventSourcingRepository to create aggregates.

Thanks.

Hi Tian,

you can just use givenState() to test state stored aggregates. It is then your own responsibility to get the aggregate into the desired state.
For testing external handlers, you can use fixture.registerCommandHandler(…).
Do note that the fixtures are designed to test aggregates, and that external command handlers are considered “additional”. If you want to test a command handler in full isolation, you should just use a “plain” unit test.

Cheers,

Hi Allard,
Thanks for your answer. But I still has problem when trying to test a non EventSource aggregate.

For example:
https://github.com/AxonIQ/axon-quick-start/blob/master/chat-scaling-out/src/main/java/io/axoniq/labs/chat/commandmodel/ChatRoom.java

if the EventSourcingHandler was removed, then the test will throw an exception.

//    @EventSourcingHandler
//    protected void on(RoomCreatedEvent event) {
//        this.roomId = event.getRoomId();
//        this.participants = new HashSet<>();
//    }

@Test
public void testCreateChatRoom() throws Exception {
testFixture.givenNoPriorActivity()
.when(new CreateRoomCommand(“roomId”, “testroom”))
.expectEvents(new RoomCreatedEvent(“roomId”, “testroom”));
}

org.axonframework.eventsourcing.IncompatibleAggregateException: Aggregate identifier must be non-null after applying an event. Make sure the aggregate identifier is initialized at the latest when handling the creation event. at org.axonframework.eventsourcing.EventSourcedAggregate.publish(EventSourcedAggregate.java:256)

Best regards,

I forgot to mention the constructor also has changed

@CommandHandler
public ChatRoom(CreateRoomCommand command) {
    this.roomId = command.getRoomId();
    apply(new RoomCreatedEvent(command.getRoomId(), command.getName()));
}

ex
Hi Tian,

From the snippets you’ve been sharing it seems like you’re mixing State-Storage and the Event Sourcing approach for saving and retrieving your Aggregates.
Those two are however not meant to be mixed.

Thus, a @CommandHandler annotated function like your sharing can publish an event and adjust state, but you cannot expect to mix that with @EventSourcingHandlers.
If you want your aggregates to be event sourced, you should never change state in the command handlers, only in the event sourcing handlers.

The AggregateTestFixtures provide two starting points for instantiating your Aggregate for the test: givenState(T state) or given(Object… events).
Similarly, there is an expectState() and expectEvents(). Just as with actual Aggregate implementation, it is not meant to mix both of those concepts in your tests (although possible).
Hence I’d suggest to pick one approach for retrieving events from the Repository, state-stored or event-sourced.

Hope this helps!

Cheers,
Steven