Once more I get into a training session on unit testing, and once more I hear “It feels wrong to change my code just for testability.”
My immediate reaction was “because the design you have right now is so good, right?” (yes, I said it out loud).
Let’s break it down.
Good Design, Bad Design
Any design is a choice. All problems have multiple solutions, and the current design you have was the chosen one. It may also look like a giant god class (or a demon class, like our subject in the picture). It’s like that because you (and others) have made design choices over weeks, months or years not to tidy it up. You may have excuses:
- I didn’t write this code
- If I change it, it may break something else
- It’s an architecture created by someone else
- I don’t have time
All may be valid, and still – excuses. You, as current caretaker of the code, decide whether to continue with the current design or change it.
Once we’ve passed that, let’s assume you want tests around this code, because why was I invited in the first place?
The reason you want tests is to enjoy their benefits. First among them: The ability to change the code with confidence. Tests (of any kind) raise your confidence about the status of your software. When you change your code for fixing bugs, adding features or just plain refactoring, you want to know things that worked, still do.
So now the question is: If you want tests (a wise choice), what are you willing to do to get them? Is changing the code part of the cost?
Again, it’s a matter of choice.
All code is testable. With tools like Typemock or PowerMockito, we can mock whatever we want. Therefore, we can write tests around code that’s packaged in any design. Or we can use less powerful tools and require to change the code in order to test and mock. There are always tradeoffs. Price, for example.
Here’s another: One of the problems I have with PowerMockito is that it sometimes throws a VerifyError (that’s unverified byte-code error, not the method-was-not-called error) which mere mortals don’t understand, and don’t know how to work around. So I’d rather persuade people to use regular Mockito than face unsolvable problems. And Mockito requires changing the code, where the “It feels wrong” discussion started.
On the other side using the power tools and leaving the code as-is is also a choice. If you built tests with PowerMockito or Isolator on crappy code, and leave the code crappy even though now you can improve it, it’s a choice (a crappy one).
Tools don’t make people write better code. They don’t allow bad code to thrive either.
Your design. Your decision.