While designing my objects I find composition to be a better choice from the perspective of testability. The reason being, I can mock parts of the composition structure if I need to, while running unit tests. This is not possible if I have an inheritance hierarchy.
I would like to know if others have also found this to be a reason to prefer composition. Also what other testability pitfalls did you get into because inheritance was used?
The Gang of Four Design Patterns book is basically all about why to prefer composition over inheritance and offers many ways to do that. Some reasons:
of classes increases the complexity of the code base
"Favor object composition over class inheritance" is actually from GoF book. This conversation with Erich Gamma describes this idea from the book.
One important pattern that requires inheritance is a template method pattern. This pattern is widely used very handy so inheritance is here to stay. Another common pattern that would use inheritance is Composite pattern. The point I try to make is that don't discount inheritance at all, but I hope it's clear from just looking at so many common APIs anyways...
I think the biggest reason why composition is easier to test is that (implementation) inheritance tends to create very coupled classes that are more fragile (Fragile Base Class) and harder to test in isolation.
Inheritance definitely has its uses, but I find myself preferring composition over inheritance more and more often.
I believe that the more you start to develop using design patterns, you'll find more and more often where composition is going to be favored over inheritance. I actually believe in the Head First: Design Patterns book that "Favor Composition Over Inheritance" is one of the primary design principles.
Your example of being able to mock up parts of the composition for testing is probably one of the best examples possible.
Edit: Although the basic principle in design patterns is to favor composition over inheritance, that doesn't mean that there aren't design patterns which utilize inheritance where it is needed. Another basic example is the decorator pattern, where you are coding towards an abstract superclass (although this is for type matching and not for implementing an "is-a" relationship).
It's not an either-or situation. They're not competitors.
Inheritance is rather easy to unit test, also. However, it sometimes requires mock concrete classes to test an abstract superclass.
Inheritance can easily be used improperly. Some designs look like "is-a" situations, but aren't really -- they're more nuanced. Sometimes it's really "behaves-like" where you need some kind of composition (a Strategy, for example) to separate behavior from other attributes.