Lesson 14 · Senior testing practice
Designing testable code and seams
Why good unit tests are usually a symptom of good decomposition — and why painful tests often reveal boundary problems, not just testing problems.
Your win: explain how seam quality affects test quality, and use test pain as a signal about code structure rather than only a signal about missing mocks.
Why this lesson is really about design
Earlier in the course, interfaces and mocks may have felt like testing mechanics. That is a useful first step, but it is not the whole picture. At a senior level, testability becomes one of the clearest windows into design quality.
If a unit is easy to isolate, easy to reason about, and easy to verify with a small test, that usually means its responsibilities are fairly well-shaped. If the test needs too many collaborators, too much setup, too many matchers, or too many weird exceptions, that is often the code telling you something important about itself.
The deeper lesson behind mocks
You can only substitute a collaborator cleanly when the production boundary is already real and understandable. That is what a seam is. A seam is not just “a place where I can inject a mock.” It is a boundary where one responsibility hands off to another responsibility in a way that the codebase can explain.
That is why the best earlier lessons in this course kept connecting test decisions back to production structure. Testability is not a cosmetic property. It is often the shadow cast by decomposition.
What test pain is trying to tell you
When a test feels painful, the first instinct is often to add more mock setup or another helper layer. Sometimes that is fine. But sometimes the pain is diagnostic.
If one unit needs a long dependency list and complicated control flow just to express one behavior, the better question may be: why does this unit need so much context to do one thing? That question often leads to a more useful fix than another matcher or another helper function.
newSuite style, that is often a hint that the unit boundary needs another look before the test gets more elaborate.Interfaces as a design seam
Re-read the interface guidance, then map it to the testing seams you have seen in spike.
→ go.dev — accept interfaces
→ docs/testing/lessons/0005-test-doubles-why-mock.html
Check yourself (from memory)
Q1. If a unit is consistently painful to test, the best first interpretation is often…
Sources. Go interface guidance; existing testing lessons.