Concrete inheritence is not "evil"

I have several friends who are constantly harping on concrete inheritence saying it's "evil" and breaks encapsulation. Though I have never heard an adequate explanation of how it breaks encapsulation, one argument I've heard is that it's impossible to unit test a class that extends another. "How do you isolate a class from its parent?" Well, you don't. That's the nature of inheritence. (For simplicity, I'm just going to say "inheritence" to mean concrete inheritence...) A subclass leverages the code of it's parent. "But you can't get 100% code coverage in your tests with inheritence!" Um, yes, you can. When I write tests and start working toward that magical 100% (3 cheers for emma!), I focus on the code that I write. Now, sometimes I own that parent class and sometimes I don't.

If I happen to own that parent class, it has its own set of tests aiming for 100% coverage. But when testing a certain class, I have no problem only worrying about this particular class. I leave testing the parent class to its owner (sometimes that's also me). Because inheritence has been abused in some circumstances, some would discard it altogether citing such problems as the fragile base class which is that when the base class changes, it can introduce instability down the line. In my experience, the proposed solution, composition and delegation, suffers the same problem.

But, anyway, back to the original question of testing classes. The question came up today of how to test the private methods on a class. What I've done in some cases is to make those methods protected so I can get at them directly (my test classes tend to live in the same package but different source tree). This works well but has the disadvantage of actually breaking encapsulation by overexposing some methods. I don't have too much of a problem with this but some might. Another option (that I haven't tested yet) is to try to use a dynamic proxy in your tests that wrap the target class and expose those methods more publicly. This doesn't require changing the actual production code but does let your tests dig as deep as they want.

What is probably the best option (and one I've really started thinking about lately), is to expand your test data set. Given a broad enough spectrum of data, you should be able to get at every single line in the class. If you can't, then perhaps that code isn't really needed. I love code coverage tools because they really let you see what you are and are not testing (at least in terms of lines of code). The problem with overreliance on those tools, is that none of them (at least that I've used) provide any metrics on the quality of your tests. There's no easy way to tell that you're testing a sufficient range of possible inputs to adequately test your code. There are some tools out there that can generate test data and that's not a bad first step. But ultimately, it comes down to your developers and how well the know and can test their code. And that's going to be true no matter what you do whether you use inheritence or not.