A boundary exercise changes one application contract and uses an observable failing assertion to determine whether the repair is correct.
Spring exercises: repair validation, ownership and rollback failures
This lesson uses the downloadable source kit: Java 21, Spring Boot 4.0.8 and its managed Spring Framework 7 dependencies. The version is pinned for repeatable builds.
Start from a failing contract
Run the source kit unchanged first. Then remove Positive from CreateReceipt while leaving the service guard: the MVC input path still rejects the zero amount, but the failure moves to the service. Remove the service guard too and observe why the direct-call contract needs its own test.
For the database exercise, move the first insert outside TransactionTemplate and let the second fail. The expected zero-row assertion should fail because the first write committed independently. Repair the transaction ownership; do not merely change the expected count.
Use separate checks for separate failures
Remove tenant from the cache key and rerun the tenant test. It should expose wrong result ownership. Remove a qualifier from report wiring and inspect the ambiguity failure. Both are correctness problems that can produce plausible successful-looking output in an insufficient test.
The answer is the original checked boundary, not a memorized string. Keep each deliberate mutation in a local copy and revert it before packaging the kit. This exercise does not submit code to a server or grade arbitrary programs.
Checked source
assertThrows(DataIntegrityViolationException.class, ledger::batchThatFails);
assertEquals(0, ledger.count());
// Repair the transaction boundary if a deliberate mutation leaves one committed row.
assertEquals("tenant-b:7", lookup.read("tenant-b", 7));Test the boundary
Run mvn test in the source-kit directory. ReceiptBoundaryTest and CoreBoundaryTest checks the behavior described here. Java excerpts belong to the named source-kit classes; they are not independent source files unless the complete class is shown.
Costs and boundaries
These exercises reuse bounded fixtures. They are local self-checks, not a hosted judge, and do not exhaustively test every database or concurrency interleaving.
Common Mistakes
- Do not change an expected result to conceal a broken contract.
- Keep transport and domain validation checks separate.
- Revert deliberate mutations before distributing source.
Read next
Spring TransactionTemplate: roll back a failed multi-row change, Spring cache keys: separate tenants and test the loader count, Spring qualifiers: select a collaborator when types are ambiguous.
