axon-testmodule, which can be obtained by configuring a maven dependency (use
<scope>test</scope>) or from the full package download.
AggregateTestFixtureallows 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,
AggregateTestFixtureis meant to test one Aggregate only. So, all commands in
given) clause are meant to target the Aggregate under test fixture. Also, all
expectedevents are meant to be triggered from the Aggregate under test fixture.
ResultValidator, respectively. The static
newGivenWhenThenFixture()method on the
Fixturesclass 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.
registerAnnotatedCommandHandlermethod. 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 the
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.
Matcheris an interface prescribing two methods:
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.
null". It is up to the Event Matchers to decide whether they accept that or not.
nullvalue. This matcher can be added as last matcher to the Exact Sequence of Events matchers to ensure that no unmatched events remain.
CallbackBehaviorobject. This object is registered using
setCallbackBehavior()on the fixture and defines if and how the callback must be invoked when a command is dispatched.
CommandBusdirectly, 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, 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
CallbackBehaviordefined on the fixture. If no explicit
CallbackBehavioris 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 a
StubSchedulerfor 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 the
StubEventSchedulerindependently of the test fixtures if you need to test scheduling of events. This
EventSchedulerimplementation 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.