Still new to java and axon, having troubles to setup integration test suite using spring and axon.
Basically, I have some process, which:
- starts with command1
- goes to command handler on aggregate and event1 is dispatched
- event1 is processed by some policy (event listener) and command2 is generated
- command2 is processed by command handler service (thus has no aggregate id) because I need to process something with third party
- event2 is dispatched and processed by another event listener, so command3 is dispatched
- command3 is processed by aggregate and event3 is dispatched
I use axon tests for unit testing aggregates and it works great.
But I would like to add "integration" tests to:
- check the whole flow, like: when command1 dispatched then event1, event2, event3 is recorded (actually don't care about fields, just to have confidence the whole thing is glued as expected)
- check the service command handler work as expected in manner "when command2 dispatched, then event2 is recorded"
I was partly succesful with 1) by doing:
package com.example.integration;
import org.axonframework.commandhandling.gateway.CommandGateway;
import org.axonframework.eventsourcing.eventstore.EmbeddedEventStore;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Arrays;
import java.util.UUID;
@RunWith(SpringRunner.class)
@SpringBootTest
@Import(IntegrationTestConfig.class)
public class ExampleIntegrationTest
{
@Autowired
private CommandGateway commandGateway;
@Autowired
private EmbeddedEventStore eventStore;
@Test
public void itShouldStoreCorrectEvents() {
var aggregateId = UUID.randomUUID().toString();
var exampleCommand = new ExampleCommand(aggregateId);
whenCommandIsDispatched(exampleCommand);
thenExpectedEventsRecorded(
Arrays.asList(
Event1.class,
Event3.class
),
aggregateId
);
}
private void whenCommandIsDispatched(Command command)
{
commandGateway.sendAndWait(command);
}
private void thenExpectedEventsDispatched(java.util.List<Class<?>> expectedEventTypes, String id)
{
var events = eventStore.readEvents(id);
while (events.hasNext()) {
Assert.assertEquals(
expectedEventTypes.get(Math.toIntExact(events.getLastSequenceNumber())),
events.next().getPayloadType()
);
}
}
}
And having IntegrationConfigTest:
package com.example.library.test;
import org.axonframework.eventhandling.EventBus;
import org.axonframework.eventsourcing.eventstore.EmbeddedEventStore;
import org.axonframework.eventsourcing.eventstore.EventStorageEngine;
import org.axonframework.eventsourcing.eventstore.inmemory.InMemoryEventStorageEngine;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
@TestConfiguration
public class IntegrationTestConfig {
@Bean
@Primary
public static EventBus createSpyEventBus() {
return new EmbeddedEventStore.Builder().storageEngine(new InMemoryEventStorageEngine()).build();
}
}
Which is nice and test passes, but I didn't find a way how to test events dispatched from the service command handler (Event2 in my example) - id of aggregate is needed here: eventStore.readEvents(id). EDIT: But I dont want to put aggregate id in, since event was not recorded on any aggregate - it was dispatched right into event gateway in service/singleton command handler.
Any ideas how can I get all dispatched events so I can also assert Event2 was dispatched?
Or am I missing something here? :)