views:

665

answers:

6

I have a question concerning unit testing. Let's say that I have several classes that inherit behaviour from a parent class. I don't want to test all the child classes for this behaviour. Instead I would test the parent class. However, I should also provide a test proving that the behaviour is available in the child classes. Do you think something like Assert.IsTrue(new ChildClass() is ParentClass) makes sense?

+6  A: 

I think that writing a test that inheritance works is a waste of time. The compiler will check that the base class methods are available if you try to use them, assuming you don't catch with intellisense. I would probably test the behavior in one child class and then only in each child class that modifies the behavior (or some state the behavior depends on).

tvanfosson
A: 

You want to unit test to make sure inheritance works??? If you don't trust your language or compiler, why are you programming?

Daniel Straight
+5  A: 

You wouldn't want to test the type of the object, unless it's coming out of an untyped factory method. Otherwise you're writing a unit test against the C# compiler which is not what you want to do.

Spence
+1  A: 

The C# compiler takes care of that kind of check for you.

If you like you can write something like:

ParentClass childClass = new ChildClass()
var testOutput = childClass.ParentMethod();
Assert.IsNotNull(testOutput);
Matthew
+1  A: 

There are two approaches you can use to test the behavior of the base class:

  1. Create a stub implementation of the base class, and unit test the stub. Only test the public methods. It's pointless to test your private and protected methods, since those will be consumed by public methods that you should test in your subclasses. This approach will not enforce that your implementations of the base class hasn't shadowed behavior incorrectly.
  2. Create test superclass for your unit tests that exercises the base class methods. Whenever you're testing a subclass of your base class, have your test class inherit from your test superclass. This approach ensures that you haven't changed the behavior of the base class inadvertently, but limits the flexability of your test.

Don't bother to verify that inheritance actually works (the whole Assert.IsTrue(new ChildClass() is ParentClass) thing). You should only test behavior. This is a structural feature of the .Net framework (inheritance), and you should trust that it works, otherwise you'll find yourself in a downward spiral of checking framework features.

Michael Meadows
+2  A: 

If you're using a state-of-the-art unit-testing framework, I don't understand the statement

I don't want to test all the child classes for this behaviour.

Your unit tests (written against an instance of the parent class) should work unchanged if you hand them an instance of a child class, provided that your child class hasn't overridden some aspect of the parent's behavior in a way that breaks the contract on the inherited methods. And that's exactly what you need to be testing, isn't it?

If you're concerned about the time it takes to run the tests, I'd double-check to make sure that your tests are partitioned such that you can selectively run tests based on what you're actively working on (but still run the full portfolio periodically to catch unintended dependencies.)

joel.neely
Amen. This is a very good reason to actually test that the "inheritance works" (ie conforms to the Liskov substitution principle) rather than just verify that child classes are subtypes of the parent class.
Sol
It's not that I'm concerned about the time it takes to run the test. I just want to write the minimum number of tests possible to make rafactoring in the future easier.
trendl