Hexagonal Architecture: Do NOT mock everything
Stop Mocking. Use Fakes, Stubs, and Spies Instead.
📅 Join me for Acceptance Testing (Live Training) on Wed 25th Feb (17:00 - 19:00 CET) (100% discount for Optivem Journal members)
🔒 Hello, this is Valentina with a premium issue of the Optivem Journal. I help Engineering Leaders & Senior Software Developers apply TDD in Legacy Code.
The most common mistake in Hexagonal Architecture is mocking everything outside the domain.
Tests break after the tiniest change.
Refactors become nightmares.
And your “clean architecture” is now just a pile of mocks.
❌ Over-Mocking Everything
Okay, Order Service Test… let’s mock all the driven ports:
- Repository? mock
- Payment Gateway? mock
- Email Service? mockBy the time your test runs, it’s fragile spaghetti:
Change a method signature in the repository? Test fails.
Change a method signature in the payment gateway? Test fails.
In the repository, I had a method add(int id, OrderData data). I refactored it to be add(Order order)… tests fail because the mock is now out-of-date.
In the payment gateway, I used the method getAllInvoices() and then did in-memory filtering to find an invoice. In my source code I decided to use the method getInvoice(String invoiceId)… tests fail because the mock now is out-of-date.
You now have hexagonal architecture… and 47 failing tests.
Why it’s bad:
Tests describe implementation, not behavior
Ports are treated as a checklist of mocks, not boundaries
Refactoring domain logic becomes a nightmare
Cognitive load goes through the roof
✅ Testing What Matters
Focus on behavior, not mocks:
✅ Fakes
✅ Stubs
✅ Spies
❌ Mocks
For the same Order Service:
- Repository → in-memory fake
- Payment Gateway → simple stub that can be configured to maybe payment succeed or fail
- Email Service → spy, whereby we collect emails in a queue, and inspect emails sentNotice the difference?
Tests now describe what the domain does, not how infrastructure works.
Refactoring domain code rarely breaks tests.
Cognitive load drops — you’re testing one thing at a time.
Fake data, not behavior. Test behavior, not calls.


