Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Test a Spring worker at admission, lease and replay boundaries

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

Worker recovery tests should assert the state left behind at each failure point, not just that an exception occurred.

Download Spring source kit

Three local observations

The bounded executor test fills one running and one waiting slot, then sees a rejected third task. The outbox test checks claim refusal before expiry, takeover at expiry and a zero-row stale acknowledgement. The consumer test verifies that a repeated event ID does not alter the stock again. Each assertion examines the state the next worker would encounter.

These are separate fixtures, not an end-to-end worker. They do not share one HTTP handler, broker or database. The layer matrix explains why a small local check cannot prove a deployment property. A useful integration test would stop a relay after commit, restart it, deliver the same event twice and inspect destination state and acknowledgement history.

Inject failure at every handoff

A larger suite should fail between receipt commit and claim, after claim but before send, after send but before acknowledgement, and after destination commit but before broker ack. Use a target database and actual broker test environment before making guarantees about lock behavior or redelivery. Record the maximum delay and retry count expected by the product. Without those values, a green unit suite can still conceal a user-visible stuck receipt.

Checked source

Java
assertThrows(TaskRejectedException.class,
    () -> executor.submit(overflowReceiptDispatch));
assertEquals(0, acknowledge(jdbc, "E-41", "stale-token"));
assertThrows(DuplicateKeyException.class,
    () -> apply(jdbc, transaction, "E-41", 4));

Verification boundary

BoundedExecutorContractTest.thirdTaskIsRejectedWhileOneRunsAndOneWaits, OutboxLeaseContractTest.expiredLeaseCanBeReclaimedButOldWorkerCannotAcknowledge and ConsumerDedupContractTest.repeatedEventIdCannotApplyTheStockMutationTwice runs in the downloadable Spring source kit. The excerpt is shortened; the kit contains the complete tests.

Costs and limits

The three assertions come from independent local tests and are condensed here. The kit has no crash injector, broker or target database. Those tests are needed to measure recovery time and verify behavior across process boundaries.

Common Mistakes

  • Do not mistake three green unit fixtures for one delivery service.
  • Do not assert only status codes when the failure is about retained state.
  • Do not omit a test for the send-before-acknowledgement gap.

Read next

Spring task executors: reject work when every slot is occupied, Spring outbox claims: allow recovery after a worker lease expires, Spring consumer deduplication: commit the event ID with the mutation.

spring
spring-boot
worker-recovery-test-matrix
Storage details