Class SagaTestFixture<T>
- Type Parameters:
T- the type of Saga under test
- All Implemented Interfaces:
AutoCloseable,ContinuedGivenState,FixtureConfiguration,WhenState
A layer over AxonTestFixture: the Saga is registered on a subscribing event processor, which handles on the
publishing thread, so a "when" call has already completed by the time the assertions run and no waiting is needed.
The Sagas are kept in an InMemorySagaStore, which the store assertions read.
The fixture's DeadlineManager is a StubDeadlineManager, so a Saga handler taking a
DeadlineManager parameter schedules on it. Nothing fires on its own: moving the fixture's time, through
whenTimeElapses(Duration) and its siblings, fires every deadline due by then in the Saga that scheduled it.
When given an event payload, the fixture resolves its Axon Framework 5 message type from that payload. When given an
EventMessage, it preserves the message's declared type. Axon Framework 5 routes by that type, so it must match
the type supported by the intended Saga handler even when the message payload has the handler's Java type.
Example:
SagaTestFixture<OrderSaga> fixture = new SagaTestFixture<>(OrderSaga.class);
fixture.givenAPublished(new OrderPlaced("order-1"))
.whenPublishingA(new OrderShipped("shipment-of-order-1"))
.expectActiveSagas(1)
.expectAssociationWith("orderId", "order-1");
A test that does not need the Axon Framework 4 API can drive the same Saga through AxonTestFixture directly
and use SagaAssertions for the store assertions.- Since:
- 5.4.0
- Author:
- Allard Buijze, Mateusz Nowak
-
Constructor Summary
ConstructorsConstructorDescriptionSagaTestFixture(Class<T> sagaType) Creates an instance for testing Sagas of the givensagaType. -
Method Summary
Modifier and TypeMethodDescriptionandThenAggregate(String aggregateIdentifier) Use this method to indicate that an aggregate with given identifier published certain events.andThenAPublished(Object event) Indicates that the giveneventhas been published in the past.andThenAPublished(Object event, Map<String, String> metadata) Indicates that the giveneventwith givenmetadatahas been published in the past.andThenTimeAdvancesTo(Instant newDateTime) Simulate time shifts in the current given state.andThenTimeElapses(Duration elapsedTime) Simulate time shifts in the current given state.voidclose()Shuts down the configuration started by this fixture.The time as the fixture's scheduler sees it.customize(UnaryOperator<MessagingConfigurer> customization) Customizes theMessagingConfigurerthe fixture builds the Saga on, for anything this interface does not expose.TheCommandBusthe Saga dispatches on.TheEventBusthe fixture publishes on.givenAggregate(String aggregateIdentifier) Use this method to indicate that an aggregate with given identifier published certain events.givenAPublished(Object event) Indicates that the giveneventhas been published in the past.givenAPublished(Object event, Map<String, String> metadata) Indicates that the giveneventwith givenmetadatahas been published in the past.givenCurrentTime(Instant currentTime) Sets the time the fixture starts from.Indicates that no relevant activity has occurred in the past.registerDeadlineDispatchInterceptor(MessageDispatchInterceptor<? super DeadlineMessage> deadlineDispatchInterceptor) Registers a deadline dispatch interceptor which will always be invoked before a deadline is dispatched (scheduled) on theDeadlineManagerto perform a task specified in the interceptor.registerDeadlineHandlerInterceptor(MessageHandlerInterceptor<? super DeadlineMessage> deadlineHandlerInterceptor) Registers a deadline handler interceptor which will always be invoked before a deadline is handled to perform a task specified in the interceptor.registerEventHandlerInterceptor(MessageHandlerInterceptor<? super EventMessage> interceptor) Registers the giveninterceptor, invoked around the Saga's event handling.registerFieldFilter(FieldFilter fieldFilter) Registers the givenfieldFilter, defining which fields are compared when matching messages.registerHandlerDefinition(HandlerDefinition handlerDefinition) Registers the givenhandlerDefinition, used to create the Saga's handlers.Registers the givenhandlerEnhancerDefinition, used to enhance the Saga's handlers.registerIgnoredField(Class<?> declaringClass, String fieldName) Indicates that a field with the givenfieldName, declared in the givendeclaringClass, is ignored when comparing messages.registerParameterResolverFactory(ParameterResolverFactory parameterResolverFactory) Registers the givenparameterResolverFactory, used to resolve the parameters of the Saga's handler methods.voidregisterResource(Object resource) Registers the givenresource, making it available to Saga handler methods declaring a parameter of an assignable type.registerStartRecordingCallback(Runnable callback) Registers the givencallback, invoked when the fixture starts recording what the Saga does, which is when the "when" phase begins.voidsetCallbackBehavior(CallbackBehavior callbackBehavior) Sets the behaviour answering commands that no subscribed handler takes.voidstop()Shuts the configuration this fixture started down.suppressExceptionInGivenPhase(boolean suppress) Sets whether a failure of a Saga handler during the "given" phase is suppressed rather than thrown.whenAggregate(String aggregateIdentifier) Use this method to indicate that an aggregate with given identifier should publish certain events, while recording the outcome.whenPublishingA(Object event) Use this method to indicate an event is published, while recording the outcome.whenPublishingA(Object event, Map<String, String> metadata) Use this method to indicate an event is published with given additionalmetadata, while recording the outcome.whenTimeAdvancesTo(Instant newDateTime) Mimic an elapsed time with no relevant activity for the Saga.whenTimeElapses(Duration elapsedTime) Mimic an elapsed time with no relevant activity for the Saga.Deprecated, for removal: This API element is subject to removal in a future version.
-
Constructor Details
-
SagaTestFixture
Creates an instance for testing Sagas of the givensagaType.- Parameters:
sagaType- the type of Saga under test
-
-
Method Details
-
withTransienceCheckDisabled
Deprecated, for removal: This API element is subject to removal in a future version.Description copied from interface:FixtureConfigurationDoes nothing, and is kept only so an Axon Framework 4 test suite still compiles.Axon Framework 4 refused a Saga holding an injected resource in a field that was not
transient, because the Saga is serialized into theSagaStoreand the resource would go with it. This method turned that check off.Axon Framework 5 has no such check, and rebuilding it would not help. It worked by comparing each field against the resource injector's list, and there is no injector; and its advice no longer applies, since
transientis a Java serialization marker while a Saga is now serialized through aConverter. A Saga can still hold infrastructure in a field, but nothing puts it there on the Saga's behalf, and serializing it fails loudly.- Specified by:
withTransienceCheckDisabledin interfaceFixtureConfiguration- Returns:
- the current FixtureConfiguration, for fluent interfacing
-
customize
Description copied from interface:FixtureConfigurationCustomizes theMessagingConfigurerthe fixture builds the Saga on, for anything this interface does not expose.The Saga, its store and its event processor are registered before the given
customizationis applied, so it can add to them or replace what they registered.- Specified by:
customizein interfaceFixtureConfiguration- Parameters:
customization- the customization to apply to the configurer- Returns:
- the current FixtureConfiguration, for fluent interfacing
-
registerResource
Description copied from interface:FixtureConfigurationRegisters the givenresource, making it available to Saga handler methods declaring a parameter of an assignable type.Registering two resources of the same type makes the last one win, as it did in Axon Framework 4. Unlike Axon Framework 4, the resource is not injected into the Saga's fields.
- Specified by:
registerResourcein interfaceFixtureConfiguration- Parameters:
resource- the resource to make available to the Saga's handler methods
-
registerParameterResolverFactory
public FixtureConfiguration registerParameterResolverFactory(ParameterResolverFactory parameterResolverFactory) Description copied from interface:FixtureConfigurationRegisters the givenparameterResolverFactory, used to resolve the parameters of the Saga's handler methods.- Specified by:
registerParameterResolverFactoryin interfaceFixtureConfiguration- Parameters:
parameterResolverFactory- the factory resolving handler method parameters- Returns:
- the current FixtureConfiguration, for fluent interfacing
-
registerHandlerDefinition
Description copied from interface:FixtureConfigurationRegisters the givenhandlerDefinition, used to create the Saga's handlers.- Specified by:
registerHandlerDefinitionin interfaceFixtureConfiguration- Parameters:
handlerDefinition- the definition creating the Saga's handlers- Returns:
- the current FixtureConfiguration, for fluent interfacing
-
registerHandlerEnhancerDefinition
Description copied from interface:FixtureConfigurationRegisters the givenhandlerEnhancerDefinition, used to enhance the Saga's handlers.- Specified by:
registerHandlerEnhancerDefinitionin interfaceFixtureConfiguration- Parameters:
definition- the definition enhancing the Saga's handlers- Returns:
- the current FixtureConfiguration, for fluent interfacing
-
registerDeadlineDispatchInterceptor
public FixtureConfiguration registerDeadlineDispatchInterceptor(MessageDispatchInterceptor<? super DeadlineMessage> deadlineDispatchInterceptor) Description copied from interface:FixtureConfigurationRegisters a deadline dispatch interceptor which will always be invoked before a deadline is dispatched (scheduled) on theDeadlineManagerto perform a task specified in the interceptor.- Specified by:
registerDeadlineDispatchInterceptorin interfaceFixtureConfiguration- Parameters:
deadlineDispatchInterceptor- the interceptor for dispatching (scheduling) deadlines- Returns:
- the current FixtureConfiguration, for fluent interfacing
-
registerDeadlineHandlerInterceptor
public FixtureConfiguration registerDeadlineHandlerInterceptor(MessageHandlerInterceptor<? super DeadlineMessage> deadlineHandlerInterceptor) Description copied from interface:FixtureConfigurationRegisters a deadline handler interceptor which will always be invoked before a deadline is handled to perform a task specified in the interceptor.- Specified by:
registerDeadlineHandlerInterceptorin interfaceFixtureConfiguration- Parameters:
deadlineHandlerInterceptor- the interceptor for handling deadlines- Returns:
- the current FixtureConfiguration, for fluent interfacing
-
registerEventHandlerInterceptor
public FixtureConfiguration registerEventHandlerInterceptor(MessageHandlerInterceptor<? super EventMessage> interceptor) Description copied from interface:FixtureConfigurationRegisters the giveninterceptor, invoked around the Saga's event handling.Interceptors are invoked in registration order, as they were in Axon Framework 4.
- Specified by:
registerEventHandlerInterceptorin interfaceFixtureConfiguration- Parameters:
interceptor- the interceptor to invoke around the Saga's event handling- Returns:
- the current FixtureConfiguration, for fluent interfacing
-
registerFieldFilter
Description copied from interface:FixtureConfigurationRegisters the givenfieldFilter, defining which fields are compared when matching messages.- Specified by:
registerFieldFilterin interfaceFixtureConfiguration- Parameters:
fieldFilter- the filter defining which fields to compare- Returns:
- the current FixtureConfiguration, for fluent interfacing
-
registerIgnoredField
Description copied from interface:FixtureConfigurationIndicates that a field with the givenfieldName, declared in the givendeclaringClass, is ignored when comparing messages.- Specified by:
registerIgnoredFieldin interfaceFixtureConfiguration- Parameters:
declaringClass- the class declaring the fieldfieldName- the name of the field to ignore- Returns:
- the current FixtureConfiguration, for fluent interfacing
-
registerStartRecordingCallback
Description copied from interface:FixtureConfigurationRegisters the givencallback, invoked when the fixture starts recording what the Saga does, which is when the "when" phase begins.- Specified by:
registerStartRecordingCallbackin interfaceFixtureConfiguration- Parameters:
callback- the callback to invoke when recording starts- Returns:
- the current FixtureConfiguration, for fluent interfacing
-
setCallbackBehavior
Description copied from interface:FixtureConfigurationSets the behaviour answering commands that no subscribed handler takes.Defaults to a
DefaultCallbackBehavior, which answersnull, as Axon Framework 4 did. A command that does reach a handler subscribed throughFixtureConfiguration.customize(UnaryOperator)is answered by that handler instead.- Specified by:
setCallbackBehaviorin interfaceFixtureConfiguration- Parameters:
callbackBehavior- the behaviour deciding what such a command returns
-
suppressExceptionInGivenPhase
Description copied from interface:FixtureConfigurationSets whether a failure of a Saga handler during the "given" phase is suppressed rather than thrown.Defaults to
false, meaning a failure during the "given" phase surfaces. Axon Framework 4'sFixtureConfigurationdocumented the opposite default while its implementation did the same as this; the implementation is what is kept.- Specified by:
suppressExceptionInGivenPhasein interfaceFixtureConfiguration- Parameters:
suppress- whether to suppress a failure during the "given" phase- Returns:
- the current FixtureConfiguration, for fluent interfacing
-
getEventBus
Description copied from interface:FixtureConfigurationTheEventBusthe fixture publishes on.Axon Framework 5 splits an
EventBusinto aEventSinkfor publishing and aSubscribableEventSourcefor subscribing. A test only needs the publishing half, but the whole bus is returned so thatfixture.getEventBus().subscribe(..)keeps working, as it did in Axon Framework 4.Axon Framework 5 obtains the bus from the application configuration. Calling this method therefore builds and starts the fixture; make all fixture registrations before requesting the bus.
- Specified by:
getEventBusin interfaceFixtureConfiguration- Returns:
- the event bus the fixture publishes on
-
getCommandBus
Description copied from interface:FixtureConfigurationTheCommandBusthe Saga dispatches on.Axon Framework 5 obtains the bus from the application configuration. Calling this method therefore builds and starts the fixture; make all fixture registrations before requesting the bus.
- Specified by:
getCommandBusin interfaceFixtureConfiguration- Returns:
- the command bus the Saga dispatches on
-
givenAggregate
Description copied from interface:FixtureConfigurationUse this method to indicate that an aggregate with given identifier published certain events.Can be chained to build natural sentences:
givenAggregate(someIdentifier).published(someEvents)- Specified by:
givenAggregatein interfaceFixtureConfiguration- Parameters:
aggregateIdentifier- The identifier of the aggregate the events should appear to come from- Returns:
- an object that allows registration of the actual events to send
-
givenAPublished
Description copied from interface:FixtureConfigurationIndicates that the giveneventhas been published in the past. This event is sent to the associated Sagas.- Specified by:
givenAPublishedin interfaceFixtureConfiguration- Parameters:
event- The event to publish- Returns:
- an object that allows chaining of more given state
-
givenAPublished
Description copied from interface:FixtureConfigurationIndicates that the giveneventwith givenmetadatahas been published in the past. This event is sent to the associated Sagas.- Specified by:
givenAPublishedin interfaceFixtureConfiguration- Parameters:
event- The event to publishmetadata- The metadata to attach to the event- Returns:
- an object that allows chaining of more given state
-
givenNoPriorActivity
Description copied from interface:FixtureConfigurationIndicates that no relevant activity has occurred in the past.- Specified by:
givenNoPriorActivityin interfaceFixtureConfiguration- Returns:
- an object that allows the definition of the activity to measure Saga behavior
-
andThenAggregate
Description copied from interface:ContinuedGivenStateUse this method to indicate that an aggregate with given identifier published certain events.Can be chained to build natural sentences:
andThenAggregate(someIdentifier).published(someEvents)- Specified by:
andThenAggregatein interfaceContinuedGivenState- Parameters:
aggregateIdentifier- The identifier of the aggregate the events should appear to come from- Returns:
- an object that allows registration of the actual events to send
-
andThenAPublished
Description copied from interface:ContinuedGivenStateIndicates that the giveneventhas been published in the past. This event is sent to the associated sagas.- Specified by:
andThenAPublishedin interfaceContinuedGivenState- Parameters:
event- The event to publish- Returns:
- an object that allows chaining of more given state
-
andThenAPublished
Description copied from interface:ContinuedGivenStateIndicates that the giveneventwith givenmetadatahas been published in the past. This event is sent to the associated sagas.- Specified by:
andThenAPublishedin interfaceContinuedGivenState- Parameters:
event- The event to publishmetadata- The metadata to attach to the event- Returns:
- an object that allows chaining of more given state
-
whenAggregate
Description copied from interface:WhenStateUse this method to indicate that an aggregate with given identifier should publish certain events, while recording the outcome. In contrast to thegivenandandThenmethods, this method starts recording activity on the event sink and command bus.Can be chained to build natural sentences:
whenAggregate(someIdentifier).publishes(anEvent)Note that if you inject resources using
FixtureConfiguration.registerResource(Object), you may need to reset them yourself if they are manipulated by the Saga in the "given" stage of the test.- Specified by:
whenAggregatein interfaceWhenState- Parameters:
aggregateIdentifier- The identifier of the aggregate the events should appear to come from- Returns:
- an object that allows registration of the actual events to send
-
whenPublishingA
Description copied from interface:WhenStateUse this method to indicate an event is published, while recording the outcome.Note that if you inject resources using
FixtureConfiguration.registerResource(Object), you may need to reset them yourself if they are manipulated by the Saga in the "given" stage of the test.- Specified by:
whenPublishingAin interfaceWhenState- Parameters:
event- the event to publish- Returns:
- an object allowing you to verify the test results
-
whenPublishingA
Description copied from interface:WhenStateUse this method to indicate an event is published with given additionalmetadata, while recording the outcome.Note that if you inject resources using
FixtureConfiguration.registerResource(Object), you may need to reset them yourself if they are manipulated by the Saga in the "given" stage of the test.- Specified by:
whenPublishingAin interfaceWhenState- Parameters:
event- the event to publishmetadata- The metadata to attach to the event- Returns:
- an object allowing you to verify the test results
-
givenCurrentTime
Description copied from interface:FixtureConfigurationSets the time the fixture starts from.- Specified by:
givenCurrentTimein interfaceFixtureConfiguration- Parameters:
currentTime- The time to start the fixture at- Returns:
- an object that allows chaining of more given state
-
andThenTimeElapses
Description copied from interface:ContinuedGivenStateSimulate time shifts in the current given state. This can be useful when the time between given events is of importance.- Specified by:
andThenTimeElapsesin interfaceContinuedGivenState- Parameters:
elapsedTime- The amount of time that will elapse- Returns:
- an object that allows registration of the actual events to send
-
andThenTimeAdvancesTo
Description copied from interface:ContinuedGivenStateSimulate time shifts in the current given state. This can be useful when the time between given events is of importance.- Specified by:
andThenTimeAdvancesToin interfaceContinuedGivenState- Parameters:
newDateTime- The time to advance the clock to- Returns:
- an object that allows registration of the actual events to send
-
whenTimeElapses
Description copied from interface:WhenStateMimic an elapsed time with no relevant activity for the Saga. If any Events are scheduled to be published within this time frame, they are published. All activity by the Saga on the command bus and event sink (meaning that scheduled events are excluded) is recorded.Note that if you inject resources using
FixtureConfiguration.registerResource(Object), you may need to reset them yourself if they are manipulated by the Saga in the "given" stage of the test.- Specified by:
whenTimeElapsesin interfaceWhenState- Parameters:
elapsedTime- The amount of time to elapse- Returns:
- an object allowing you to verify the test results
-
whenTimeAdvancesTo
Description copied from interface:WhenStateMimic an elapsed time with no relevant activity for the Saga. If any Events are scheduled to be published within this time frame, they are published. All activity by the Saga on the command bus and event sink (meaning that scheduled events are excluded) is recorded.Note that if you inject resources using
FixtureConfiguration.registerResource(Object), you may need to reset them yourself if they are manipulated by the Saga in the "given" stage of the test.- Specified by:
whenTimeAdvancesToin interfaceWhenState- Parameters:
newDateTime- The time to advance the clock to- Returns:
- an object allowing you to verify the test results
-
currentTime
The time as the fixture's scheduler sees it.This is the time of the fixture's
StubDeadlineManager. Axon Framework 4 reported the time of its event scheduler, which it moved in step with the deadline manager.- Specified by:
currentTimein interfaceFixtureConfiguration- Returns:
- the current time of the fixture's scheduler
-
stop
public void stop()Shuts the configuration this fixture started down.New in Axon Framework 5: the fixture runs a started
AxonConfiguration, which holds an event processor that has to be stopped. -
close
public void close()Shuts down the configuration started by this fixture.This alias for
stop()allows a fixture to be used in a try-with-resources statement, ensuring that Axon Framework 5 lifecycle handlers run even when a test fails.- Specified by:
closein interfaceAutoCloseable
-