PublishedEvents records in-process events during a module test; it can assert both one accepted event and no event after rejection.
Spring Modulith PublishedEvents: assert an accepted fact and a rejected silence
Match by business identity
The source-kit test filters ReceiptReserved by receiptId. It sees one event for RECEIPT-203 after a valid reservation and none for RECEIPT-211 after a rejected 59-unit request. Checking a business key prevents an unrelated event of the same Java type from satisfying the assertion.
Observe the right thing
PublishedEvents records application publication in the test context. It does not establish listener completion, a persisted registry entry or broker acceptance. For an asynchronous listener, a Scenario test needs an explicit deadline and a state or event expectation. The event boundary names the later delivery steps.
Check the negative path
The rejected command leaves the fixture balance unchanged and emits no successful fact. This is more useful than testing only the happy path: a false success event would let dispatch act on inventory that was never reserved.
Checked excerpt
assertThat(events.ofType(ReceiptReserved.class)
.matching(ReceiptReserved::receiptId, "RECEIPT-203")).hasSize(1);Cost and verification
Event assertions add little runtime cost beyond the Spring test context. A real publication registry writes one record per transactional listener and needs cleanup policy. The source kit checks the stated local behavior.
Common Mistakes
- Do not interpret one published event as broker delivery.
- Do not assert only the event type when multiple receipts can publish it.
- Do not emit a success event for a rejected reservation.
Read next
Spring Modulith module slices: start inventory without dispatch, Spring Modulith events: publish a domain fact after a valid state change, Spring Modulith event registry recovery: separate publication, listener and broker states, Spring transaction events: run a listener after commit without claiming durability.
