One should not test private functions but the public API only.
If the public API is not passing a test, it is most likely that your private functions are buggy.
This advice is good, but it certainly does not apply 100% of the time.
Sometimes the public API can work fine and pass all tests even though the private functions aren't doing their job correctly.
Consider a public function that takes a URL and a callback. It makes a request to the URL and invokes the callback with the response once it's completed. In addition to simply making a request, there are some private, helper functions that do some caching behind the scenes so that you never make the same request twice.
If you were to simply test that public function, you would never know if the cache was working properly or not because if it was broken, you'd just do the request as normal.
Your approach is interesting, but to me there is still a little discomfort. And the case study with the cache, don't convinced me to deviate from testing only the public interface.
You said, how can I test the cache functionality in a private function. However, it is easy to test this on the public interface, too.
some pseudo-code:
suite: test caching:
#second request should response content from first response:
- set TTL 3600
- set equal (create)timestamp to cache-test-foo.html and test-cache-bar.html (both with different content)
- copy test-cache-foo.html to test-cache.html
- reqA = request test-cache.html .. test & save response ....
- copy test-cache-bar.html to test-cache.html
- reqB = test-cache.html .. test % save result
- compare reqA === reqB, because it should be the cached result
I think with some more tests you can prove all cases.
And if your cache functionality achieved such great complexity, you should rather think about to outsource it to an independent module.
Finally, it should be said, thanks for the food for thought, maybe I get in this situation, I'm be able to use your proceeding. :-)
Testing the private functions to know which one is buggy is a better option, IMHO.
The last part of the article, with private testing / stripping debugging variable / public testing, looks like a good practice.