4 ms·
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. While
by revscat 13y ago
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. While there are ways around this -- reflection, PowerMock, probably others -- they all tend to be ugly and hackish.
This has an effect upon the design of classes, because the easiest path is simply to make private methods package private. This is frequently not the ideal design, and taken to its logical extreme means that you will have no private methods.
I think unit testing is important, and do use it. The line for me, though, is similar to DHH's here: when the drive for unit testing affects the design of the software, that's when I tend to become less enamored.
- j_baker 13y agoI don't think you need to avoid private methods in Java. Rather, I think you should ask yourself if a private method is really necessary. Secondly, you should be asking yourself how you can test private code via the class's public methods.
- yesiamyourdad 13y agoAgree with that. If you want to unit test something, you should be able to test the outputs for a given set of inputs, plus possibly verify some interactions, i.e. if I call chargeCustomersCreditCard(BillingInfo billing, Invoice invoice), then there will be exactly one call to myCreditCardProcessingMock.chargeTheCard(String creditCardNumber, Decimal amount), where creditCardNumber == billing.creditCardNumber and amount == invoice.totalAmount.
- twistedpair 13y ago> I don't think you need to avoid private methods in Java. I think the reverse question is better in Java. Does this method/class need to be public? Only expose the bare minimum in the API so that you retain free reign within your codebase.
- matwood 13y agoTests should be testing a classes public interface, not the private methods that may or may not drive the public interface. What this type of design will push is to stick with the Single Responsibility Principle. If you find yourself wanting to test a lot of individual private methods you have likely violated SRP.
- dragonwriter 13y ago> 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.
- Strilanc 13y agoI 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.
- kerkeslager 13y ago> 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.