Subclass To Test Discussion

I've been using JavaUnit lately, and have come up with the following technique that I think might make a good idiom.

I have a class (let's call it AppThingy). I want to test it. So that the tests can get at AppThingy non-public methods, I first wrote ThingyTest (a subclass of TestCase) as an inner class of AppThingy. I realized, however, that doing so would force everyone who wants to use the AppThingy class to have JUnit.

Therefore, I created a subclass of AppThingy called AppTestThingy and moved the inner class there. Now instances of ThingyTest can poke around in AppThingy objects, yet AppThingy itself is "test-free".

-- BillTrost


SubclassToTest is an AntiPattern. See SubclassToTestAntiPattern.


See also: SubclassToTest


I agree with Bill, sometimes you have to get inside the class to make it do things it doesn't normally. If you didn't like subclassing, you'll hate ThrowYourOwnException! Unless you get inside the class, you are just TestingByPokingAround. I have adopted Bill's idea as SubclassToTest. -- JohnFarrell

Unless I'm missing something here, you say that I am just TestingByPokingAround if my automated unit tests access the class being tested using only the API available to any client class. Please enlighten me. -- KielHodges

If your class is deterministic and self-contained, unit tests which call the class and check the answer (CallAndCheckResult) should be good enough. But if your class depends on external systems which have a lot of state, such as servers across networks, or shared databases, you need to go much further than that. Making sure that the class gives the right answer under strictly controlled conditions is only just scratching the surface in these cases, and that is why I claim it is TestingByPokingAround. For more confidence, you need techniques like FakeTheSideEffects and ThrowYourOwnException. Sorry for my blanket statement, but testing distributed non-deterministic systems is my focus at the moment. -- JohnFarrell

Java anonymous inner classes are great for this. You want a server that blows up the third time some calls it? No problem - right there in the test.


SubclassToTest when you want to override a simple factory method to produce a mock object.

 interface BInterface { ... };

class B implements BInterface { ... };

class A { private BInterface mB; public A() { mB = makeNewB(); }; protected BInterface makeNewB() { return new B(); } .... }

test class... { class MockB implements BInterface { .... };

class TestA extends A { protected BInterface makeNewB() { return new MockB(); } }

... use TestA .... }


Replacing a method with a testable method by subclassing strikes me as mocking that method, hence PartialMock? which I have tried to automate (http://www.lastcraft.com/partial_mocks_documentation.php).


Recently I have seen SubclassToTest a convenient way to test LegacyCode, typically when you want remove some functionality from a class needed to collaborate with the ClassUnderTest. -- ErikMeade


I find it preferable to separate my tests into a parallel package structure and build both tests and production code into the same directory. This way my tests have access to all the methods that other classes could have access to (public, protected and default) but I can still hide things from my tests (in private methods). I have always been leery of keeping test code with my production code, especially in the same compilation unit. It becomes very hard (read as harder than necessary) to ship production code without the tests when the tests are part of the production classes (which is the case with Inner Classes). Even subclasses do not have access to private methods so this method is functionally the same as Bill's method at the top of this page but it does not create two classes for each class to test (AppTestThingy and ThingyTest).


See MockObject for another way doing this kind of testing.


EditText of this page (last edited July 24, 2008) or FindPage with title or text search