Favour composition over inheritance
Polymorphism with seams
Part thirteen of a series of posts about automated testing.
The idea that object composition is to be preferred to class inheritance goes back a long way - it is discussed in the Gang of Four “Design Patterns” book from 1995. More recently, programming languages are appearing which avoid including inheritance at all (e.g. Golang and Rust).
Let’s imagine Santa’s sleigh can use either reindeer or a jet engine as a source of power. Here’s an approach that uses inheritance to share code between the implementations:
When it comes to unit testing these classes, it is difficult to isolate the behaviour which is unique to the power source for testing. You need to instantiate and load presents onto the sleigh to test we are calling the names of the reindeer correctly (and loading that many presents will make the tests slow).
In general there is no “seam” between the child and the parent class, so you are forced to test them together.
Compare with the composition approach, where testing the collaborators in isolation will be trivial: