AggregateSpec
Base class for writing aggregate specification tests using a domain-specific language (DSL).
AggregateSpec provides a declarative way to define comprehensive test scenarios for domain aggregates using the Given/When/Expect pattern. It leverages JUnit 5's dynamic test capabilities to generate multiple test cases from a single specification, including branching scenarios via forks.
This class is designed for behavior-driven development (BDD) style testing of aggregates, allowing complex state transitions and command validations to be expressed fluently.
Key features:
Declarative test definition using DSL
Support for branching test scenarios with forks
Automatic generation of dynamic JUnit 5 tests
Type-safe aggregate testing with generics
Integration with dependency injection for mocking services
Example usage:
class CartSpec : AggregateSpec<Cart, CartState>({
on {
val addCartItem = AddCartItem(productId = "item1", quantity = 1)
givenOwnerId("owner123")
whenCommand(addCartItem) {
expectNoError()
expectEventType(CartItemAdded::class)
expectState { items.assert().hasSize(1) }
fork("Remove Item") {
val removeCommand = RemoveCartItem(productIds = setOf("item1"))
whenCommand(removeCommand) {
expectEventType(CartItemRemoved::class)
expectState { items.assert().isEmpty() }
}
}
}
}
})Author
ahoo wang
Parameters
the type of the command aggregate
the type of the state aggregate
the DSL block that defines the test scenarios