Why I Don't Consider Subclass to Test An Anti-Pattern
How do we reconcile “Don’t mock what you are testing” and the Subclass to Test technique? In short, I use Subclass to Test in order to start moving in the direction of the design I want without making a significant commitment to moving in that direction. This way I tend to avoid many of the chain-reaction refactorings that I tend to find in legacy code, so I avoid the distraction of wanting to make those changes while I’m trying to focus on this one. I see Subclass to Test as a necessarily evil on the path towards a more cohesive design.
Since I prefer not to mock part of a module in order to test another part of it, when I do this, it acts like a big comment reading, “Don’t stop here. Continue improving the design.” I use Subclass to Test in order to no longer need to use Subclass to Test. I mock part of a module in order to know which parts to separate from each other with the goal of no longer mocking one part in order to test another.
Finally, I should note that mocking part of a module to test another part of it doesn’t always lead to trouble. I consider it a risk, but not always a problem. I sometimes make the conscious choice to let this happen. Even so, I tend to consider all legacy code “guilty until proven innocent”.
The question which prompted this answer was removed from Stack Overflow, so I have pasted it here.
Sometimes when you deal with legacy code you find it hard to break the dependencies. One of the solutions that some unit-testing gurus (e.g. Roy Osherove in The Art of Unit Testing or Michael Feathers in Working Effectively with Legacy Code) propose is to use the "Subclass and override" technique. The idea of this technique is to encapsulate the usage of dependency in protected method and then test the extended class with that method overridden with method that uses fake dependency.
Also there are two more techniques that, imo, are doing almost the same. Those are:
- mock the protected method that contains dependency
- use reflection (if it is supported in your language) to make the dependency-containing protected method to return what is needed
However the latter two techniques are considered to be anti-patterns (you don't mock what you are testing). But, to me, all three techniques are using the same idea. Is the "Subclass and override" technique also considered an anti-pattern and if not, why?
The phrase "you don't mock what you are testing" seems to be confusing so I should probably explain myself. Though only one method of the class is mocked, AFAIK, the fact of mocking the part of the class under test is considered to be bad practice because it breaks encapsulation and exposes implementation details to the test.