How to leverage the MagicNumber pattern #IRL ?
Magic what?
When you start reading about and trying Test-Driven Development (TDD), you very often discover the coding kata practice. And you see that the next move to answer the first failing test is to return a hardcoded value that greens the test. With the prime factors kata, it would look similar to the following.
expect(primeFactorsOf(1492)).to.deep.equal([2, 2, 373])
let primeFactorsOf = (number) => [2, 2, 373]
[2, 2, 373], hardcoded value, the MagicNumber code smell. Some identify here a Duplication code smell instead.
Then what?
And how is that useful in real life?
Next move
Assuming the coding kata practice is useful for real life, I want the practice to build up my muscle memory.
What works well for me is to move the MagicNumber inside my architecture, creating it if needed. In the context of a coding kata, it could mean something like the following.
expect(primeFactorsOf(1492)).to.deep.equal([2, 2, 373])
let primeFactorsOf = (number) => {
let max = new Mathematician();
return max.primesOf(number);
}
class Mathematician {
primesOf(number) {
return [2, 2, 373];
}
}
We moved the MagicNumber. The test is still green.
What is the next move now? Now I have the opportunity to triangulate with an internal test against the Mathematician class, instead of writing another external test. This is also something I want to practice. I don’t want to rely only on external tests. Remember the test pyramid!
In real life
In real life, starting something new usually makes me start with an external test and the MagicNumber starting position is within a web adapter in the context of a web app.
Keeping the idea of moving the MagicNumber, we make it travel the hexagonal architecture like the message going through the domain, the outbound http layer of the web client, the server endpoint, …
Maybe you like to drive the show with internal tests along the way to specify what you want from each component. If you do so then triangulating against the component currently answering with MagicNumber will make it disappear from this component and the external test will turn red again. This is when you move the MagicNumber to the next component to come back to green.
Be careful with that approach though because having too many internal tests too early could easily jeopardize your refactoring options. If you stick to the rule of not writing new test during refactoring then a fair question could be: when to add internal tests with outside-in TDD? We will cover that in another article.
Eventually we remove the MagicNumber from the code and the external test stays green.
We’re done 🙂
Leave a Reply