3

I thought I was aware of when the private keyword should be used. Encapsulation is the reason for this and as such I have made the effort to make all methods private where possible.

I have just written a post on testing and was told that it is a bad idea to be testing with reflection on my private methods and it is bad code design. Why is this the case, the fact my key code is hidden / encapsulated is a good thing and should that not be tested because that is really the crux of what my public facing code relies on?

Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
Biscuit128
  • 5,218
  • 22
  • 89
  • 149
  • See also the discussions in this Stack Overflow question: [What's the proper way to test a class with private methods using JUnit?](http://stackoverflow.com/questions/34571/whats-the-proper-way-to-test-a-class-with-private-methods-using-junit) – avandeursen Mar 05 '12 at 12:17

6 Answers6

6

Good tests try to achieve a high code path coverage, so yes, testing private methods is good thing to do. But why do you call them directly by using reflection? The fact that these methods are private usually indicates the presence of a public/protected methods using them. So the test of public methods implies the test of private methods.

Simon
  • 9,255
  • 4
  • 37
  • 54
  • 1
    tht actually makes a lot of sense! Ok, so really the private methods at somepoint will be used by public / protected so why test both public and private when we can just do the public which covers it all? – Biscuit128 Mar 04 '12 at 12:48
  • That's what I'm talking about :) – Simon Mar 04 '12 at 12:54
4

Since private methods are not part of your public interface, you are free to change them whenever you want. If you test your private methods directly though, such changes will break tests. That is why you should only test the public interface of your code, not the private methods.

@Simon also raises a good point. If you follow a strict test-first approach, then you will only write public methods. Private methods will be created mostly (if not exclusively) through refactoring.

Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
1

The main point of encapsulation is that it will allow you to change internal behavior without breaking others code ( ie you refactor 3 private methods to 1 ). If you test these internal methods you'll break the test if you change them. Furthermore now you'll think twice before changing them restricting your self from improvements.

If you want to test your methods are correct, do test the effect they cause on a public method.

OscarRyz
  • 196,001
  • 113
  • 385
  • 569
1

A good design approach is to start with only public methods and test them very well. At some point, your public methods will grow and become big and that is when refactoring should kick in. Use refactoring to break down and extract private methods from the public ones. This will result in a good private method coverage as they contain code that used to be in public methods covered by your unit tests. Reflection might be easy to use for you but think of your colleagues who will take over your code, they might not be as good as you ;)

GETah
  • 20,922
  • 7
  • 61
  • 103
0

Usually unit testing using to test the public interface of classes. Many smart guys do not recommends testing for private methods. I agree with this because testing of all functions is a lot of boring work. For my experience good coverage for public interfaces is enough to make a reliable software.

asktomsk
  • 2,289
  • 16
  • 23
0

See Testing Private Methods with JUnit and SuiteRunner by Bill Venners.

卢声远 Shengyuan Lu
  • 31,208
  • 22
  • 85
  • 130
  • 1
    This link is a good article, but a link-only answer is not a good answer on Stack Overflow (for reasons of link rot). Could you put the key points from the article in the answer? – Paŭlo Ebermann Mar 04 '12 at 17:12