Mock vs Fake: what test doubles say about how you think.
While going through the
@grafana backend architecture, I noticed something subtle but important. Test doubles aren’t treated as a testing detail. They’re treated as a design signal.
Most discussions around test doubles stay superficial. Mocks vs fakes. Coverage numbers. Tooling.
But the deeper question is this:
What does your code assume about the world?
If your business logic assumes:
- a database must exist
- a network must respond
- another service must behave
then your system isn’t just hard to test. It’s tightly coupled to reality.
Test doubles challenge that assumption.
They ask:
- can this logic exist without infrastructure?
- can behavior be reasoned about in isolation?
- can intent survive implementation changes?
Mocks and fakes answer different philosophical questions.
Mocks ask:
- did the conversation happen the way I expected?
Fakes ask:
- what does the system actually do?
That’s why architectures like
@grafana's quietly favor fakes. They model a small, controlled reality and reveal design flaws early.
Here’s the uncomfortable truth.
If test doubles feel painful to introduce, it’s rarely a testing problem. It’s a boundary problem.
Good test doubles don’t just enable tests.
- they expose assumptions
- they enforce contracts
- they keep complexity at the edges
In the end, test doubles are less about testing correctness and more about preserving meaning as systems grow, change, and outlive their original context.
That’s a design choice, not a testing one.