$ mvn -pl saga test -Dtest=ChoreographyHappyPathTest (real embedded Kafka broker via @EmbeddedKafka; ChoreographySagaStarter.placeOrder() publishes OrderCreated, and every step after that is a listener reacting to the previous one's event -- no single class decides the whole saga) Order 1 status: CONFIRMED Stock remaining for GADGET-1: 8 Payment record status: RESERVED [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 Stock started at 10, the order asked for 2, and 8 is what's left -- the reservation really ran. Five separate listeners fired in sequence to get here: PaymentChoreographyListener reacted to OrderCreated and reserved payment; InventoryChoreographyListener reacted to PaymentReserved, found enough stock, and published InventoryReserved; OrderChoreographyListener reacted to that and confirmed the order. None of those three classes knows about the other two's existence -- each one only knows "when I see event X, I do Y, then publish Z".