This subject came in my mind after having discussion with my colleague who creates methods with default or protected scope to ease testing.
I’m not sure why even think that you should test your private methods. At least when you’re coding with TDD, you create one test, which test that method does what it should. After you get your test pass, you create another one, and another one. As long as you feel that it’s necessary to add functionality to method.
When your method does what you want it to do, it’s time to refactor. While refactoring, you should run tests every time change is made, so that it’s easier to notice if/when you break something. Tests are something you rely during refactoring.
After refactoring, you probably have method which uses private methods which you made to make code more readable and reusable. Now, think few minutes what would happen if you change visibility of those methods from private to for example protected or default.
First, you can create tests for those methods and be happy. BUT, what about refactoring the public method you create at first place? Right, you cannot do it without touching those tests! Of course modern IDEs will rename methods or parameters almost automatically, but you lose your trust to your tests. If you change something, there is always possibility to break tests.
Let’s think it from another point of view. Assume that you are working with project which has 2-3 full time developers. Then, on one pretty day, team gets a new member. This new member gets a task to add new functionality to some old classes which has tests. This new member starts with writing tests that fails. Then s/he starts to implement the method itself. After all tests are passing, s/he wants to refactor as there is same behavior on multiple places. Now, if someone has done his job right, there is tests only for public methods and our new member can refactor and trust that s/he doesn’t break anything as long as tests are passing.
If there is protected or default methods with their own tests, s/he probably need to touch them as well. This creates a situation where new bugs might be introduced.
Think about it, your tests should test that method does what it should do. Not how it does it or how many private methods are used to gain passing test.
In the other hand what is the purpose of the private method? I’d say its purpose is to make code more readable and reusable in that specific class. Nothing else.