Subclass to test is a cool idea invented by BillTrost.
I've adopted it as a method of TacticalTesting (thanks Bill).
The idea is that by subclassing a class, you can get access to its
protected (and presumably package protected, since you are the developer
and hence can add code to the same package) methods in order to test them.
The benefits of this approach are:
You don't have to ship the testing subclass, so the customer never sees your testing code.
You don't have to change your tested class at all.
The drawbacks are:
You pollute your package namespace.
You still can't do all the WhiteBoxTesting you want, e.g. if there are private methods and variables.
Classes that instantiate the tested class can't be hardwired to the class name. There are heaps of ways around that, but they're not as clean as just invoking a constructor.
A more important drawback, is that by subclassing you are possibly changing the behavior of the superclass and invalidating your test results -- TimMackinnon
Doctor, doctor, it hurts every time I do this! [patient grabs elbow and twists violently]
Don't do that.
Sorry, but if you do that, aren't you just being clumsy (not that I
am ever clumsy...) -- BillTrost
I prefer the technique suggested in the JUnit FAQ (at least the one that comes with JUnit3.2 for Java). There, you duplicate your package structure in a separate test directory that you put in your class path. This way you can use both package and protected-access variables and methods without having to subclass and you don't have to worry about polluting your package name space either. -- Scott Langley
[In response to some AbstractTest comments that were moved to that page...]SubclassToTest is not for perfect class hierarchies. In less than perfect hierarchies, often you have dependencies on things that either make your setup very difficult (for example, direct database calls) or things that make your tests take a long time to run (roundtripping on a network for instance). I don't mind violating encapsulation on a class that is hiding too much. Often it is the first step towards making things better.
See SubclassToTestDiscussion. Contrast AbstractTest.