Hacker News new | past | comments | ask | show | jobs | submit login

> In Java, the most obvious example of testing affecting the design of a class is the necessity of avoiding private methods in order to facilitate testing.

IMO, this is unnecessary and a failure to understand the point of unit testing: unit testing is testing the public interface of the unit-under-test in isolation from other components, so there is no reason to avoid private methods to facilitate testing since private methods are, ipso facto, not part of the public interface of the unit under test, they are called by methods in the public interface and tested by testing the methods which they serve. Making private methods public and directly testable makes unit tests more brittle and refactoring more expensive, which is exactly the opposite of what you should be striving for with unit testing.




I disagree. For example, a method to generate all the permutations of a sequence is easy to get wrong and should be tested whether or not the library using it exposes it.

Testing an internal method by itself, instead of indirectly through the public API, gives you the same scope reduction benefits that testing a unit instead of the entire program gives (but less pronounced).

Personally I think the solution is to scope unit tests into the thing they are testing. So tests of a private method would be scoped to that method. That way your decisions about what to test aren't constrained, though they can be guided, by what is visible.


> For example, a method to generate all the permutations of a sequence is easy to get wrong and should be tested whether or not the library using it exposes it.

There are three possibilities here:

1. If your language or common utility libraries have a permutations() method, you shouldn't be rolling your own permutations() method because one exists in libraries. 2. If you're in an environment that doesn't have built in permutations() you should group these kinds of very generic functions that are hard to get right in to some sort of utility module (in which case it would necessarily already be public). 3. If you're in a language that doesn't have built in permutations() and permutations() is in the class which uses it, you have a very generic function on a more specific class, where it has no business being, so it should be moved to a utility class.

In all three cases, the solution isn't just "make it public". If you find that you're just making something public to unit test it, this usually points to a much larger problem with your design.


1. Agreed. (Assume it doesn't.)

2. Why am I making my library's utility methods public? It's a frob library, not a generic utility method library. I don't want clients depending on my utility methods. I don't want to support a separate utility library just to avoid testing private methods. I would prefer not to take on an external dependency for a single simple method. Having it private and tested is the best tradeoff here.

3. Agreed.


The point of unit testing, or any testing, is to make sure that the code does what it should. Public vs. private interfaces are philosophical distinctions in determining what is a "proper" unit test, and do not help in validating functionality. In order to validate that functionality testing frequently requires making changes to the class structure that would otherwise not be needed.

(Aside: I did not say private methods need to be made public to facilitate unit tests. They do, however, need to be made at least package private; this annoys me.)




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: