Some good arguments have already been made here:
TDD your code. This will make sure your code does not need to test private methods.
In your example, you talked about a main method. That is only the input/output. There should be a class that is free of side effects that. An be tested. Then, there might be a parse and toString method that will be utilized by the main method. Both can also be tested. That why a lot of people value TDD: It leads to a clean and testable code.
Absolutely agree! But, I think TDD can sometimes ignore the fact that there is tons of code out there that doesn’t or can’t follow it.
In this particular case, we had a class that couldn’t be instantiated (no public constructor), so the only way to interact with it was through the main method. The only way (I can think of) to put the solution in a testable state would be to write some public wrapper function that accepted everything but the IO streams. Since that function was never going to be used outside of testing, I didn’t bother, but it would have gotten the job done.
Hmm, why not refactor the class then? If it’s untested legacy code, it is legitimate to test private methods and use things like PowerMock to mock static methods etc. But that should be the first step. Once the tests capture the behavior, you should refactor the class bit by bit and start writing new unit tests until you can throw away the old I/O based tests. I’ve done this once for a rather large code base. It was both tedious and soothing at the same time. After a lot of work, I had a tested code base, deleted 1/3 of the code and the application was 10x as fast. 😅
I am actually 100% on board with working toward eliminating private method tests and whatnot. That said, I guess I’m just critical of rules that we tend to blindly follow as a community.
We're a place where coders share, stay up-to-date and grow their careers.
We strive for transparency and don't collect excess data.