You really shouldn't. The public methods is the interface to the surrounding code, and that is what you want to make sure works. How you implement it, with private methods or 3rd party libs is up to you. If a bug in a private method makes it past your unittests of public methods, there was an edgecase you didn't test for.
It's also a matter of praticality - I simply odn't have time to write tests for each and every method.
You have some tests to ensure your public methods don't change implementation.
That isn't the purpose of all tests.
A complex public API should consist of smaller private parts. When you change those smaller parts of code, you would like to know if you break something and specifically what you broke. Testing of a small, isolated chunk of code is the 'unit' in the term 'unit tests'.
Unit tests on actual units of code allow you to more quickly isolate failures.
I test all public methods. Anything private is part of the implementation for those metods, and rarely would I want to test that. If I make a breaking change in a private method, and the public unittest does not test it, it's an edge case I didn't test for, or the public method is too broad.
I don't and that is not why I'm testing either. I'm testing so the contract (i.e. public methods) other developers rely on does not change. That said, I can see in the build history what checkin caused the test to fail, so I would still know where to look.
Well yeah that's the view being taken to its logical conclusion here:
- Private methods are just an implementation detail with respect to the public methods. (You really care about whether the public methods reply correctly.)
- Public methods are just an impdet with respect to the module API. (You really care about whether the module's public surface replies correctly.)
- The module's API is JAID with respect to the user/game API. (You really just care about whether the gamer gets the right responses to controller inputs.)
- The user/game API is JAID wrt to the code/gamer interface. (You really just care about whether the gamer likes what you've written.)
- The code/gamer interface is JAID wrt the company/customer interface. (You really just care whether people still give you money.)
- The company/customer interface is JAID wrt the investor/company interface. (You really just care whether the venture throws off more money than you put in.)
Nevertheless, you'd still like to catch the failures as soon and as narrowly as possible!
Absolutes and exaggerated conclusions are no good. As long as a test ensure we do not introduce old bugs (regression) and help me refactor to the point where the time spend writing and maintaining the test is less than I save, then it's golden. I just never had a need to test a private method - I do have to deliever a working piece of code, and unit- and integration tests help me knowing I have met the spec.
Tests that help you fix failures are great - just be sure they're helping more than they're hurting.
Beyond that I think the key is to test the things you don't expect to change. The user always needs to be able to log in. But I expect developers will rearrange the private method boundaries.
To go further: define an API, write tests against that API, and then do a pass of dead-code analysis on the resulting library-plus-test-suite. Any private functions left uncalled by your public API can just be removed!
To counter that I'd say you should have a test case to cover the leap year handling is working as expected. If you aren't testing that since it wasn't in the spec, than why would you have the code at all?
It's also a matter of praticality - I simply odn't have time to write tests for each and every method.