views:

435

answers:

4

I'm currently writing an implementation of a JDBC driver (yes, you read that correctly) in a TDD manner and while I have only finished class stubs at this point and only some minor functionality, it just occured to me that since Statement is a superclass for PreparedStatement which is a superclass for CallableStatement, what should I do when I really start to write tests for my implementations of those classes, which one of these should I do:

  1. Create a test suite for Statement and then extend that suite for additional tests for PreparedStatement and then do the same for CallableStatement.
  2. Test each implementation individually ignoring the methods inherited from superclass(es).
  3. Rigorously test every single method individually for each implementation class; It is possible that some inherited methods work differently depending on implementation after all. Mild variation of this would be that I'd test all those inherited methods the implementation uses.

Number two feels the most natural but due to the reason I put to the third one I'm not that sure if it'd be wise to do so. So, what do you think I should do?

+1  A: 

Provide enough tests so that you feel comfortable - based on your knowledge of the implementation. I don't treat unit testing as completely black-box testing. If you know that the base class never calls any virtual methods (or at least none that are overridden) then note that fact but don't effectively duplicate the unit tests that you've already got.

Unit testing can certainly be taken to extremes - it's always worth balancing the value you're getting from it with the effort it's costing you.

Jon Skeet
+1  A: 

I would specifically never do alternative 1 (letting the test-class hierarchy be the same as the actual class hierarchy) if this means you will be running the same tests repeatedly for each test subclass. I am also generally sceptical of subclassing test classes other than the general utility base class.

I normally make 1 test for each class in a hierarchy, abstract or not. So the base class has a separate test (usually with a test-local private subclass that is used for testing it specifically), and I use my knowledge of the subclasses to write proper tests for each subclass. I can see in coverage runs what is missing tests, so I'm usually not too formalized up-front.

krosenvold
A: 

With TDD, you should not aim at testing methods, but behavior, or capabilities of your code. Therefore, when implementing a subclass, you can restrict to testing only the behaviors that are different from the base class. When in doubt, write a new test.

philippe
+1  A: 

"test every single method individually for each implementation class"

In particular, failure to override a superclass method properly is a common bug. The author of the subclass makes assumptions about the superclass. The superclass changes, and the subclass is now broken.

S.Lott