When code is hard to test, it is usually a design problem. Code becomes difficult to test for many of the same reasons it becomes difficult to main...
For further actions, you may consider blocking this person and/or reporting abuse
Great topic testable code is really about clean structure, low coupling, and clear responsibilities. Most anti-patterns come from trying to optimize for speed over maintainability.
The "fix" for global mutable state is only applicable if the value is incidentally mutable. That is, it just happens to be mutable, and its mutability is not part of the design of the code. If the mutability is part of how the code works, then you still need to fix it, but the fix is almost certainly going to be much more involved.
Interesting take. Could you please provide an example where having a global mutable state would be part of the design?
Well, prior to about 1970, pretty much all non-trivial programs included global mutable state. COBOL doesn't have any other option, for example. And in Fortran, COMMON blocks, which were a standard way to pass data among subroutines, are an example global mutable state.
Moving to more modern times, global flags are commonly used in many programming languages, and are often mutable at runtime (as opposed to program startup).
Have you ever written JavaScript code, or used a JavaScript library, that modified an object's prototype? If so, you've mutated global state.
The framing of "hard to test = design problem, not a testing problem" is something every dev should internalize early — it reframes the whole conversation.
The anti-pattern that trips up teams the most in my experience is #5, mixing business logic with I/O. It seems harmless at first, but it quietly makes entire service layers untestable without a running network. And the fix is so clean once you see it.
The note on interfaces is also refreshingly honest — "inject infrastructure, not pure business logic" is a much better mental model than the blanket "everything needs an interface" advice you see everywhere. Solid, practical guide
Glad you found it useful. Thank you!
started noticing this during code reviews - the code that was hardest to read was always hardest to test too. same root cause: too much responsibility per function.
Absolutely right! But the opposite is not always true. For example, a method that directly depends on a random number generator can be easy to read, but impossible to test.
fair - non-determinism is its own category. inject the rng and it's usually testable again. what gets you is when both problems compound.
Great overview, good points, clear examples, well done!
Thank you!
Well done!
Thank you!