Class CommandHandlingTestFixture<C extends Command>
- Type Parameters:
C- the command type
CommandHandler or CommandHandlerDefinition. This class can be used in favor of the
CommandRouter to test command handling logic without interacting with the event
store, solely relying on a set of StateRebuildingHandlerDefinitions. No event
upcasting, event type resolution, or
meta-data propagation is involved during
test execution.
This class follows the Given When Then style of representing tests with a fluent API supporting:
- given state initialization based on in-memory events and meta-data
Commandexecution to execute theCommandHandlerunder test- assertions to verify the command executed as expected, including verification of the events published by the command handler under test
this may look as follows. The StateRebuildingHandlerDefinitions needed to
mimic event sourcing as well as the CommandHandler definition under test have been omitted for brevity.
@Test
public void bookAdded() {
UUID bookId = UUID.randomUUID();
CommandHandlingTestFixture
// specify state rebuilding handler definitions to use
.withStateRebuildingHandlerDefinitions(...)
// specify command handler (definition) to test
.using(...)
.givenNothing()
.when(
new AddBookCommand(
bookId,
"Tolkien",
"LOTR",
"DE234723432"
)
)
.expectSuccessfulExecution()
.expectSingleEvent(
new BookAddedEvent(
bookId,
"Tolkien",
"LOTR",
"DE234723432"
)
);
}
In lack of the event store, for StateRebuildingHandler.FromObjectAndRawEvent.on(Object, Object, Event) and
StateRebuildingHandler.FromObjectAndMetaDataAndSubjectAndRawEvent.on(Object, Object, Map, String, Event) the
given state initialization uses stubbed raw Events, instead, based on the
following contents:
| event attribute | value derivation |
|---|---|
Event.source() |
is set to a fixed value and cannot be overridden |
Event.subject() |
is set to Command.getSubject(), but can be overridden using usingSubject(String) or per event using CommandHandlingTestFixture.Given.GivenEvent.subject(String) |
Event.type() |
is set to a fixed value and cannot be overridden |
Event.data() |
is set to an empty map and cannot be overridden |
Event.specVersion() |
is set to a fixed value and cannot be overridden |
Event.id() |
is set randomly, but can be overridden per event using CommandHandlingTestFixture.Given.GivenEvent.id(String) |
Event.time() |
is set to the value from givenTime(Instant), or CommandHandlingTestFixture.Given.andGivenTime(Instant), or Instant.now() by default, but can be overridden per event using CommandHandlingTestFixture.Given.GivenEvent.time(Instant) |
Event.dataContentType() |
is set to a fixed value and cannot be overridden |
Event.hash() |
is set to a random value and cannot be overridden |
Event.predecessorHash() |
is set to a random value and cannot be overridden |
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classBuilder forCommandHandlingTestFixture.static classFluent API helper class for asserting a captured events.classFluent API helper class encapsulating the results of aCommandHandlerexecution for assertion.classCommandHandlingTestFixture.Given<C extends Command>Fluent API helper class encapsulating the current state stubbing prior to executing theCommandHandlerunder test. -
Method Summary
Modifier and TypeMethodDescriptionInitializes theCommandHandlingTestFixturewith the given event payloads applied in order to the configuredStateRebuildingHandlerDefinitions to reconstruct the instance state.Initializes theCommandHandlingTestFixtureusing theCommandHandlingTestFixture.Given.GivenEventconsumer for more fine-grained event specification of the events and their meta-data, which will be applied in order to the configuredStateRebuildingHandlerDefinitions to reconstruct the instance state.<AnotherCommand extends Command>
CommandHandlingTestFixture<C>.Given<C> givenCommand(CommandHandlingTestFixture<AnotherCommand> fixture, AnotherCommand command) Execute the givenCommandwithout meta-data using theCommandHandlerDefinitionencapsulated within the given fixture to capture any new events published, which in turn will be applied tothis.<AnotherCommand extends Command>
CommandHandlingTestFixture<C>.Given<C> givenCommand(CommandHandlingTestFixture<AnotherCommand> fixture, AnotherCommand command, Map<String, ?> metaData) Execute the givenCommandwith meta-data using theCommandHandlerDefinitionencapsulated within the given fixture to capture any new events published, which in turn will be applied tothis.Initializes theCommandHandlingTestFixturewith no prior state.<I> CommandHandlingTestFixture<C>.Given<C> givenState(I state) Initializes theCommandHandlingTestFixturewith the given instance state.Initializes theCommandHandlingTestFixturewith no prior state, but a specific time-stamp.usingSubject(String subject) Specifies theEvent.subject()to be used for subsequent calls toCommandHandlingTestFixture.Given.andGiven(Object...).static <I> CommandHandlingTestFixture.Builder<I> withStateRebuildingHandlerDefinitions(StateRebuildingHandlerDefinition<I, ?>... definitions) Creates aCommandHandlingTestFixture.Builderinstance for the givenStateRebuildingHandlerDefinitions.
-
Method Details
-
withStateRebuildingHandlerDefinitions
public static <I> CommandHandlingTestFixture.Builder<I> withStateRebuildingHandlerDefinitions(StateRebuildingHandlerDefinition<I, ?>... definitions) Creates aCommandHandlingTestFixture.Builderinstance for the givenStateRebuildingHandlerDefinitions.- Type Parameters:
I- the generic type of the instance to be event sourced before handling the command- Parameters:
definitions- theStateRebuildingHandlerDefinitions to be used to mimic event sourcing for theCommandHandlerunder test- Returns:
- a
CommandHandlingTestFixture.Builderinstance
-
givenNothing
Initializes theCommandHandlingTestFixturewith no prior state. This should be used for testingCommandHandlers using a pristine subject.- Returns:
- a
CommandHandlingTestFixture.Giveninstance for further fluent API calls
-
givenTime
Initializes theCommandHandlingTestFixturewith no prior state, but a specific time-stamp. This should be used, if further events shall be applied with thatEvent.time().- Parameters:
time- the initialization time-stamp- Returns:
- a
CommandHandlingTestFixture.Giveninstance for further fluent API calls
-
givenState
Initializes theCommandHandlingTestFixturewith the given instance state. This can be used in favor of the preferred event based initialization, if the latter one is too complex, for instance requiring too many events.- Type Parameters:
I- the generic state type- Parameters:
state- the initialization state- Returns:
- a
CommandHandlingTestFixture.Giveninstance for further fluent API calls
-
usingSubject
Specifies theEvent.subject()to be used for subsequent calls toCommandHandlingTestFixture.Given.andGiven(Object...).This is a convenience method to be used in favor of specifying event subjects using
CommandHandlingTestFixture.Given.GivenEvent.subject(String), which, if used, however, takes precedence over the subject defined using this method. Notice, that the event subject specified by this method does not affect calls toCommandHandlingTestFixture.Given.andGivenCommand(CommandHandlingTestFixture, Command).- Parameters:
subject- the event subject to be applied to any subsequent given events- Returns:
- a
CommandHandlingTestFixture.Giveninstance for further fluent API calls - See Also:
-
given
Initializes theCommandHandlingTestFixturewith the given event payloads applied in order to the configuredStateRebuildingHandlerDefinitions to reconstruct the instance state.- Parameters:
events- the events to be applied- Returns:
- a
CommandHandlingTestFixture.Giveninstance for further fluent API calls
-
given
public CommandHandlingTestFixture<C>.Given<C> given(Consumer<CommandHandlingTestFixture.Given.GivenEvent> event) Initializes theCommandHandlingTestFixtureusing theCommandHandlingTestFixture.Given.GivenEventconsumer for more fine-grained event specification of the events and their meta-data, which will be applied in order to the configuredStateRebuildingHandlerDefinitions to reconstruct the instance state.- Parameters:
event- event specification consumer, at leastCommandHandlingTestFixture.Given.GivenEvent.payload(Object)must be called- Returns:
- a
CommandHandlingTestFixture.Giveninstance for further fluent API calls
-
givenCommand
public <AnotherCommand extends Command> CommandHandlingTestFixture<C>.Given<C> givenCommand(CommandHandlingTestFixture<AnotherCommand> fixture, AnotherCommand command) Execute the givenCommandwithout meta-data using theCommandHandlerDefinitionencapsulated within the given fixture to capture any new events published, which in turn will be applied tothis. This is mostly used forCommandHandlers publishing a lot or more complex events, in favor of stubbing the events directly.Be aware that stubbed events can be specified more precisely than captured ones, since the encapsulated
CommandHandleris responsible for event publication using theCommandEventPublisher. Hence,CommandHandlingTestFixture.Given.GivenEvent.time(Instant)andCommandHandlingTestFixture.Given.GivenEvent.id(String)cannot be specified using this approach.- Type Parameters:
AnotherCommand- generic command type to execute- Parameters:
fixture- the fixture holding the command to executecommand- the command to execute for event capturing- Returns:
- a
thisfor further fluent API calls - Throws:
AssertionError- in case the given command did not execute successfully
-
givenCommand
public <AnotherCommand extends Command> CommandHandlingTestFixture<C>.Given<C> givenCommand(CommandHandlingTestFixture<AnotherCommand> fixture, AnotherCommand command, Map<String, ?> metaData) Execute the givenCommandwith meta-data using theCommandHandlerDefinitionencapsulated within the given fixture to capture any new events published, which in turn will be applied tothis. This is mostly used forCommandHandlers publishing a lot or more complex events, in favor of stubbing the events directly.Be aware that stubbed events can be specified more precisely than captured ones, since the encapsulated
CommandHandleris responsible for event publication using theCommandEventPublisher. Hence,CommandHandlingTestFixture.Given.GivenEvent.time(Instant)andCommandHandlingTestFixture.Given.GivenEvent.id(String)cannot be specified using this approach.- Type Parameters:
AnotherCommand- generic command type to execute- Parameters:
fixture- the fixture holding the command to executecommand- the command to execute for event capturingmetaData- the command meta-data- Returns:
- a
thisfor further fluent API calls - Throws:
AssertionError- in case the given command did not execute successfully
-