Ask HN: Do you test private methods? (Programming)

2 points by eecks ↗ HN
I read online that it is bad practise to test private methods and that you are then testing the internals of your class.. but..

I think this reasoning is too strict. Sometimes your private methods won't need testing but having a hard rule just seems silly.

What if I have a private method that calls out to a service and manipulates the result. I would want to test that. I could put it in it's own class and make it public.. but why would I? It's cleaner, easier to understand, easier to refactor and easier to test when it is just a private/protected method.

3 comments

[ 1.7 ms ] story [ 28.4 ms ] thread
A assume you're asking about unit testing. Private methods should be tested of course, but not directly. Unit tests should mimic how the code is actually used in a real application. So call the public methods, and those will in turn call the private methods so that everything gets tested.

When you write unit tests that call private methods directly that makes your tests brittle and creates disincentives to refactoring. Developers should be able to freely refactor the internal design of a class as long as the public API remains unchanged. But if you have a bunch of unit tests calling private methods then they have to update all those tests as well, and so refactoring becomes so difficult that developers tend to just not do it. This causes accumulation of technical debt.

Personally when I am writing new code I will often write some temporary unit tests for private methods just to act as scaffolding until I get the higher-level public methods working correctly including the tests for same. Then I throw away the private method unit tests before pushing the new code to the master branch.

> Developers should be able to freely refactor the internal design of a class as long as the public API remains unchanged

Is refactoring the only reason for doing this? To me it seems that when a developer refactors code they should also refactor the tests.

If everything (including private methods) are tested then the refactoring should be easier because they know ALL the code is working in the way it was tested. If there are a bunch of private methods that aren't tested then refactoring them could introduce new bugs that aren't covered in the unit tests testing the public API.

You need some way to have this method receive receive test content from a fake (mock) service. Manipulate that mock input and test the public interface. It's enough.