Documentation
¶
Overview ¶
Package scenario contains utilites for testing different parts of a system built with eventually, such as Aggregate Roots, Command Handlers, etc.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AggregateRootGiven ¶
type AggregateRootGiven[I aggregate.ID, T aggregate.Root[I]] struct { // contains filtered or unexported fields }
AggregateRootGiven is the state of the scenario once the Aggregate Root preconditions have been set through the AggregateRoot().Given() method.
This state gives access to the When() method to specify the domain command to test using the desired Aggregate Root.
func (AggregateRootGiven[I, T]) When ¶
func (sc AggregateRootGiven[I, T]) When(fn func(T) error) AggregateRootWhen[I, T]
When allows to call the domain command method on the Aggregate Root instance provided by the previous AggregateRoot().Given() call.
The domain command must be called inside the required closure parameter.
type AggregateRootInit ¶
type AggregateRootInit[I aggregate.ID, T aggregate.Root[I]] struct { // contains filtered or unexported fields }
AggregateRootInit is the entrypoint of the Aggregate Root scenario API.
An Aggregate Root scenario can either set the current evaluation context by using Given(), or test a "clean-slate" scenario by using When() directly.
func AggregateRoot ¶
func AggregateRoot[I aggregate.ID, T aggregate.Root[I]](typ aggregate.Type[I, T]) AggregateRootInit[I, T]
AggregateRoot is a scenario type to test the result of methods called on an Aggregate Root and their effects.
These methods are meant to produce side-effects in the Aggregate Root state, and thus in the overall system, enforcing the domain invariants represented by the Aggregate Root itself.
func (AggregateRootInit[I, T]) Given ¶
func (sc AggregateRootInit[I, T]) Given(events ...event.Persisted) AggregateRootGiven[I, T]
Given allows to set an Aggregate Root state as precondition to the scenario test, by specifying ordered Domain Events.
func (AggregateRootInit[I, T]) When ¶
func (sc AggregateRootInit[I, T]) When(fn func() (T, error)) AggregateRootWhen[I, T]
When allows to call for a domain command method/function that creates a new Aggregate Root instance.
This method requires a closure that return said new Aggregate Root instance (hence why no input parameter) or an error.
type AggregateRootThen ¶
type AggregateRootThen[I aggregate.ID, T aggregate.Root[I]] struct { // contains filtered or unexported fields }
AggregateRootThen is the state of the scenario where all parameters have been set and it's ready to be executed using a testing.T instance.
Use the AssertOn method to run the test scenario.
func (AggregateRootThen[I, T]) AssertOn ¶
func (sc AggregateRootThen[I, T]) AssertOn(t *testing.T)
AssertOn runs the test scenario using the specified testing.T instance.
type AggregateRootWhen ¶
type AggregateRootWhen[I aggregate.ID, T aggregate.Root[I]] struct { // contains filtered or unexported fields }
AggregateRootWhen is the state of the scenario once the domain command to test has been provided through either AggregateRoot().When() or AggregateRoot().Given().When() paths.
This state allows to specify the expected outcome on the scenario using either Then(), ThenFails() or ThenError() methods.
func (AggregateRootWhen[I, T]) Then ¶
func (sc AggregateRootWhen[I, T]) Then(v version.Version, events ...event.Envelope) AggregateRootThen[I, T]
Then specifies a successful outcome of the scenario, allowing to assert the expected new Aggregate Root version and Domain Events recorded during the domain command execution.
func (AggregateRootWhen[I, T]) ThenError ¶
func (sc AggregateRootWhen[I, T]) ThenError(err error) AggregateRootThen[I, T]
ThenError specifies an unsuccessful outcome of the scenario, where the domain command execution fails with an error.
Use this method when you want to assert that the error retured by the domain command execution is of a specific type or value.
func (AggregateRootWhen[I, T]) ThenFails ¶
func (sc AggregateRootWhen[I, T]) ThenFails() AggregateRootThen[I, T]
ThenFails specifies an unsuccessful outcome of the scenario, where the domain command execution fails with an error.
Use this method when there is no need to assert the error returned by the domain command is of a specific type or value.
type CommandHandlerGiven ¶
type CommandHandlerGiven[Cmd command.Command, T command.Handler[Cmd]] struct { // contains filtered or unexported fields }
CommandHandlerGiven is the state of the scenario once a set of Domain Events have been provided using Given(), to represent the state of the system at the time of evaluating a Command.
func (CommandHandlerGiven[Cmd, T]) When ¶
func (sc CommandHandlerGiven[Cmd, T]) When(cmd command.Envelope[Cmd]) CommandHandlerWhen[Cmd, T]
When provides the Command to evaluate.
type CommandHandlerInit ¶
CommandHandlerInit is the entrypoint of the Command Handler scenario API.
A Command Handler scenario can either set the current evaluation context by using Given(), or test a "clean-slate" scenario by using When() directly.
func CommandHandler ¶
func CommandHandler[Cmd command.Command, T command.Handler[Cmd]]() CommandHandlerInit[Cmd, T]
CommandHandler is a scenario type to test the result of Commands being handled by a Command Handler.
Command Handlers in Event-sourced systems produce side effects by means of Domain Events. This scenario API helps you with testing the Domain Events produced by a Command Handler when handling a specific Command.
func (CommandHandlerInit[Cmd, T]) Given ¶
func (sc CommandHandlerInit[Cmd, T]) Given(events ...event.Persisted) CommandHandlerGiven[Cmd, T]
Given sets the Command Handler scenario preconditions.
Domain Events are used in Event-sourced systems to represent a side effect that has taken place in the system. In order to set a given state for the system to be in while testing a specific Command evaluation, you should specify the Domain Events that have happened thus far.
When you're testing Commands with a clean-slate system, you should either specify no Domain Events, or skip directly to When().
func (CommandHandlerInit[Cmd, T]) When ¶
func (sc CommandHandlerInit[Cmd, T]) When(cmd command.Envelope[Cmd]) CommandHandlerWhen[Cmd, T]
When provides the Command to evaluate.
type CommandHandlerThen ¶
type CommandHandlerThen[Cmd command.Command, T command.Handler[Cmd]] struct { CommandHandlerWhen[Cmd, T] // contains filtered or unexported fields }
CommandHandlerThen is the state of the scenario once the preconditions and expectations have been fully specified.
func (CommandHandlerThen[Cmd, T]) AssertOn ¶
func (sc CommandHandlerThen[Cmd, T]) AssertOn( t *testing.T, handlerFactory func(event.Store) T, )
AssertOn performs the specified expectations of the scenario, using the Command Handler instance produced by the provided factory function.
A Command Handler should only use a single Aggregate type, to ensure that the side effects happen in a well-defined transactional boundary. If your Command Handler needs to modify more than one Aggregate, you might be doing something wrong in your domain model.
The type of the Aggregate used to evaluate the Command must be specified, so that the Event-sourced Repository instance can be provided to the factory function to build the desired Command Handler.
type CommandHandlerWhen ¶
type CommandHandlerWhen[Cmd command.Command, T command.Handler[Cmd]] struct { CommandHandlerGiven[Cmd, T] // contains filtered or unexported fields }
CommandHandlerWhen is the state of the scenario once the state of the system and the Command to evaluate have been provided.
func (CommandHandlerWhen[Cmd, T]) Then ¶
func (sc CommandHandlerWhen[Cmd, T]) Then(events ...event.Persisted) CommandHandlerThen[Cmd, T]
Then sets a positive expectation on the scenario outcome, to produce the Domain Events provided in input.
The list of Domain Events specified should be ordered as the expected order of recording by the Command Handler.
func (CommandHandlerWhen[Cmd, T]) ThenError ¶
func (sc CommandHandlerWhen[Cmd, T]) ThenError(err error) CommandHandlerThen[Cmd, T]
ThenError sets a negative expectation on the scenario outcome, to produce an error value that is similar to the one provided in input.
Error assertion happens using errors.Is(), so the error returned by the Command Handler is unwrapped until the cause error to match the provided expectation.
func (CommandHandlerWhen[Cmd, T]) ThenFails ¶
func (sc CommandHandlerWhen[Cmd, T]) ThenFails() CommandHandlerThen[Cmd, T]
ThenFails sets a negative expectation on the scenario outcome, to fail the Command execution with no particular assertion on the error returned.
This is useful when the error returned is not important for the Command you're trying to test.