Thursday, September 6, 2012

Testing Private Methods

You shouldn't test private methods.

There, wasn't that simple? Perhaps too simple, so allow me to explain...

This debate seems to pop up on the internet and amid various developer groups from time to time. Should we test private methods? It's a simple yes-or-no question (or, even simpler, it's a "no" question), and there seems to be an encampment of zealous opinions on both side. I, of course, am no exception to that. The thing is, I've yet to hear any good argument in favor of such practice. And I don't believe there is one.

First of all, consider the argument that we should "test everything." With that statement I wholeheartedly agree. But how do you define "everything"? Certainly you should test all outward-facing (read: public) functionality. So, by extension, this would also test all private functionality, would it not? If you have private functionality that isn't being used by the public functionality... Then why do you have it? If nothing is using it, get rid of it.

Suppose you do test your private methods, perhaps through some trickery of the language or some reflection of assemblies of whatever. Then what do you do if your implementation changes?

Let's say you have some repository which uses a database and you write tests against that functionality. But the repository also has private helper methods for handling common database tasks, so you write tests against those as well. Now let's say you swap out that repository implementation with one that saves to an XML file. The public functionality should be identical so as to not be a breaking change to the rest of the code. But it is a breaking change to the tests. The private helper methods are all different, so the tests need to be updated in order to test the same interface.

This, of course, is unacceptable.

Private is just that... private. You mark something as private when you feel that it's a detail which needn't be known to the rest of the code. It's not part of the interface. Well, the tests are part of the rest of the code. They're not special. They're not some one-off thing that hangs onto the side of the codebase. They're classes and methods like anything else. If something is private, your tests shouldn't know about it. And if they shouldn't know about it, then certainly they shouldn't try to directly use it.

Seriously, can anybody present a compelling reason why a private method should ever be tested? Why code which by design is entirely unknown should somehow be examined?

No comments:

Post a Comment