Saturday, July 21, 2007

Unit Testing Private Methods

So I've always thought that when it comes to writing unit tests against private methods, you have two options; use reflection, or break encapsulation. However, I just read an article that discusses this very topic in a good amount of detail. It points out 4 options for testing private methods.

If you're just interested in a summary of those 4 options, keep reading. Otherwise, here is the article I came across.

1. Don't Test Private Methods

  • If you're testing the class's non-private methods, then the private methods are being tested indirectly. You can maintain a high confidence level in your code w/o unit testing those private methods.

  • Feeling the need to test private methods may indicate that those methods should be moved into their own class. There they would become non-private (easily tested) and become reusable as well.

  • 2. Break Encapsulation
  • Changing the method from private to package-access is probably the quickest and easiest solution to testing private methods.

  • Seeing a private methods tells you something. When it's package-access, it doesn't speak so loudly.

  • 3. Use Reflection
  • Using reflection (java.lang.reflect), you can bypass encapsulation and gain access to the private method you'd like to test.

  • Your tests are more verbose. You've got to gain access to the private method before you can test it.

  • 4. Use an Inner Class
  • An inner class inside the class you're testing will have access to the private methods.

  • Your production class contains more than production code.

  • My $.02
    I really don't like the idea of using a nested test class, but I'd love to hear arguments promoting this option. Also, I don't like sacrificing encapsulation for the sake of testing. If you want to test the private method, do it right and use reflection. Other than that, I'm sure indirectly testing private methods has its time and place, but how often is determined by how you write your code.

    No comments: