Re: What are Your JUnit Pain Points, Really?
Posted: Nov 9, 2009 11:35 AM
> You mentioned... "But you only test the public methods!"
> Why wouldn't we want to test our private methods, too?
It wasn't me mentioning it, but... let's recap TDD.
Test Driven Development means you write a test, and then write the code to make the test work. This way, the development you do is driven by the tests you write.
So, let's go back to those tests you write. What tests should you do? First, you don't think of implementation. It should be no concern whatsoever to you what the implementation is when you write the tests.
What you should concern yourself with is... what do you use that class for? Your tests are effectively a double for the client code of that class.
This is one important point, for many reasons. On of those reasons is that you don't make your class more complex than strictly needed to handle the requirements of the client code, as represented by the tests.
So, the direct consequence of it is that you write tests for the API of the class, and the contract that class has to abide by.
And those things are represented by the public methods. The private methods are just implementation, and you do not concern yourself with it. You just ensure that the API is providing what it must.
Which goes back to many of Uncle Bob's points. For instance, mock a lot -- if you test an API, then:
1) Having an interface for it is not only reasonable, but a good practice.
2) Having an stable API is important. Control its version as you expect the libraries you use to control theirs: minor revisions when the API changes in ways that break forward compatibility, and major revisions when the API changes in ways that breaks backward compatibility. Yes, for pretty much every class you write.
Any changes to *how* you go about doing the stuff becomes invisible. It reduces bugs introduced by subtle changes in a class that you think shouldn't be a problem, and makes you work that little bit harder at maintaining the API stable.
Also, because you write the API from the PoV of the client code, you are already optimizing API for usage, which is the main reason for refactoring that changes the public methods of a class.
Or that, at least, is the theory. And it is a learning experience all of its own.