Notice what this function is not doing: no DB call, no HTTP, no global state. Clear input → clear output. That's it.
The question that changed everything
"How would I unit test this?"
We didn't always know how to write good code. But whenever we got stuck on a design decision, we asked this one question — and it guided us every time.
If the answer was "I'd need to spin up a DB" → the class was doing too much
If the answer was "I'd need to mock 5 things" → the dependencies were wrong
If the answer was "I'd need to change global state" → that's a design smell
The pain of testing is the signal. Don't suppress it — follow it.
Single Responsibility: the north star
A function or class that does one thing:
Is trivially unit-testable
Has clear inputs and outputs
Can be changed without fear
Can be understood in isolation
SRP isn't just a clean code principle — it's the prerequisite for unit testability.
THE RULE
If your test setup is painful, your code is doing too much.
Stop trying to write the test. Start asking what needs to be split.
Why This Matters for Tech Leads
Confidence
Your team can change code without fear. New engineers can modify existing code on day one.
Sustainability
Modular, well-tested code stays maintainable as the codebase grows. Less "don't touch that" code.
Velocity
Less debugging, fewer regressions, faster onboarding. The upfront cost pays back many times over.
AI-Readability
Unit-testable code — clear inputs, single responsibility, no hidden state — is exactly what AI agents parse and reason about best. This is how we write code for the future.
Being Pragmatic
TDD shines when...
Business logic & domain rules
Clear inputs → expected outputs
APIs and service interfaces
Bug fixes (write test that reproduces, then fix)
Refactoring existing code
TDD struggles when...
Exploratory / prototyping work
UI layout and visual design
You don't yet know what to build
Heavily integrated external systems
One-off scripts & spikes
A good tech lead promotes TDD as a default mindset, not a rigid mandate.
Addressing the Pushback
❝"It slows me down"
It slows you down now. It speeds up the team next month. Tech leads think in weeks, not hours.
❝"I'll write the tests after"
After-the-fact tests verify implementation, not behavior. You also lose the design benefit.
❝"Our code is too coupled for TDD"
That's exactly why you need it. TDD makes coupling visible and painful — which motivates decoupling.
Putting It Together
Pyramid
Where to invest
+
Unit-testable code
SRP · isolation · clear interfaces
=
Clean, maintainable, AI-ready code
Ship without fear. Grow without rot.
Ask not "do we have tests?" Ask "can we unit test this — and if not, why not?"
Resources
Further Reading
Mike Cohn — Succeeding with Agile (origin of the Test Pyramid)
Martin Fowler — The Practical Test Pyramid (martinfowler.com)
Kent Beck — Test-Driven Development: By Example
Ham Vocke — The Practical Test Pyramid (martinfowler.com)
Ian Cooper — "TDD, Where Did It All Go Wrong" (talk)