Revised one of my earliest contributions to the evolutionary design community: abstract test cases and their evolution into contract tests
I started out by wanting a Nunjucks filter to reverse a collection of posts, from which I would later “take 10”, but then I realized I could simply program by intention.
We removed duplication as part of fixing a defect. Doing this helped us see more clearly both how to understand and fix the defect.
In the process of refactoring an 11ty configuration, I ran into an error message that I had to work hard to understand. Fortunately, microcommitting made it relatively easy to diagnose and fix the problem.
Writing “too many”
if conditions can cause problems in code, but I think we’d all feel better understanding why this might be the case, rather than merely repeating received wisdom.
The production implementation of an interface can fail, but the lightweight implementation that you use for testing can’t fail in the same way. How do you check that the client is handling that kind of failure? Use another kind of test double.
To some it feels a bit wrong, but it feels quite natural to me: I often need to refactor just before writing the next failing test. Indeed, that seems like a good practice on its face!
You understand the benefits of refactoring, but you still feel a strong impulse to rewrite larger pieces of your system. You believe that refactoring would be safer and more effective, but it feels too slow for you to choose to do it under the pressure of an industrial-strength situation. What does that mean? What can you do?
If you read enough articles on TDD and testing, you’ll find authors who view mocks with significant suspicion. I think that they criticize the symptom and not the cause. If you count yourself among these people, then you don’t hate mocks, you hate side-effects. I don’t hate side-effects, but I feel glad that I’ve learned how to refactor away from them.
If you’re wondering about whether you should hand-roll your test doubles (mock objects) or use a library, then this article will help you.
Many senior programmers feel nervous allowing their project’s design to evolve in the hands of their co-workers. This article shows one specific example of how a useful abstraction and a small type hierarchy can evolve by following simple design guidelines that anyone can learn.