axon-test
module, which can be obtained by configuring a maven dependency (use <artifactId>axon-test</artifactId>
and <scope>test</scope>
) or from the full package download.AggregateTestFixture
allows you to configure a certain infrastructure, composed of the necessary command handler and repository, and express your scenario in terms of given-when-then events and commands.NoteSince a unit of testing here is the Aggregate,AggregateTestFixture
is meant to test one Aggregate only. So, all commands inwhen
(orgiven
) clause are meant to target the Aggregate under test fixture. Also, allgiven
andexpected
events are meant to be triggered from the Aggregate under test fixture.
FixtureConfiguration
, TestExecutor
and ResultValidator
, respectively. The static newGivenWhenThenFixture()
method on the Fixtures
class provides a reference to the first of these, which in turn may provide the validator, and so forth.NoteTo make optimal use of the migration between these stages, it is best to use the fluent interface provided by these methods, as shown in the example above.
registerAnnotatedCommandHandler
method. Besides the Annotated Command Handler, you can configure a wide variety of components and settings that define how the infrastructure around the test should be set up.DomainEventMessage
. If the "given" event implements Message, the payload and meta data of that message will be included in the DomainEventMessage, otherwise the given event is used as payload. The sequence numbers of the DomainEventMessage are sequential, starting at 0.givenCommands(...)
" method to provide Command objects.NoteDuring the execution of the test, Axon attempts to detect any illegal state changes in the Aggregate under test. It does so by comparing the state of the Aggregate after the command execution to the state of the Aggregate if it sourced from all "given" and stored events. If that state is not identical, this means that a state change has occurred outside of an Aggregate's Event Handler method. Static and transient fields are ignored in the comparison, as they typically contain references to resources.You can switch detection in the configuration of the fixture with thesetReportIllegalStateChange
method.
equals()
) with their counterparts in the actual Events. If one of the properties is not equal, the test fails and an extensive error report is generated.Matcher
is an interface prescribing two methods: matches(Object)
and describeTo(Description)
. The first returns a boolean to indicate whether the matcher matches or not. The second allows you to express your expectation. For example, a "GreaterThanTwoMatcher" could append "any event with value greater than two" to the description. Descriptions allow expressive error messages to be created about why a test case fails.Matchers.listWithAllOf(event matchers...)
Matchers.listWithAnyOf(event matchers...)
Matchers.sequenceOf(event matchers...)
null
". It is up to the Event Matchers to decide whether they accept that or not.Matchers.exactSequenceOf(event matchers...)
Matchers.equalTo(instance...)
Matchers.andNoMore()
or Matchers.nothing()
null
value. This matcher can be added as last matcher to the Exact Sequence of Events matchers to ensure that no unmatched events remain.Matchers.messageWithPayload(payload matcher)
Matchers.payloadsMatching(list matcher)
CallbackBehavior
object. This object is registered using setCallbackBehavior()
on the fixture and defines if and how the callback must be invoked when a command is dispatched.CommandBus
directly, you can also use Command Gateways. See below on how to specify their behavior.fixture.registerResource(Object)
method with the resource as parameter. The fixture will detect appropriate setter methods or fields (annotated with @Inject
) on the Saga and invoke it with an available resource.TipIt can be very useful to inject mock objects (e.g. Mockito or Easymock) into your Saga. It allows you to verify that the saga interacts correctly with your external resources.
registerCommandGateway(Class)
and registerCommandGateway(Class, Object)
. Both methods return an instance of the given class that represents the gateway to use. This instance is also registered as a resource, to make it eligible for resource injection.registerCommandGateway(Class)
is used to register a gateway, it dispatches Commands to the CommandBus managed by the fixture. The behavior of the gateway is mostly defined by the CallbackBehavior
defined on the fixture. If no explicit CallbackBehavior
is provided, callbacks are not invoked, making it impossible to provide any return value for the gateway.registerCommandGateway(Class, Object)
is used to register a gateway, the second parameter is used to define the behavior of the gateway.whenTimeElapses()
. All events will have the timestamp of the moment the test fixture was created.NoteThe Fixture uses aStubScheduler
for time based activity, such as scheduling events and advancing time. Fixtures will set the timestamp of any events sent to the Saga instance to the time of this scheduler. This means time is 'stopped' as soon as the fixture starts, and may be advanced deterministically using thewhenTimeAdvanceTo
andwhenTimeElapses
methods.
StubEventScheduler
independently of the test fixtures if you need to test scheduling of events. This EventScheduler
implementation allows you to verify which events are scheduled for which time and gives you options to manipulate the progress of time. You can either advance time with a specific Duration
, move the clock to a specific date and time or advance time to the next scheduled event. All these operations will return the events scheduled within the progressed interval.