Brendan Enrick

Daily Software Development

Testing Private Methods

In a previous post about cutting large classes down in size I mentioned that

Sometimes there are methods kept private in a class. Some calculations are kept private because nothing should be calling those methods on this class. This is a good hint that the method belongs somewhere else. If the method is kept private because it doesn't make sense for a user of this class to use it, it belongs somewhere else.

Private methods are a common occurrence in classes. Sometimes they should be moved into another class, because they were only private because they didn't make sense in that class. Other times they are part of the internal workings of the class. At the end of the day it is always up to the developer how he is going to structure his code.

If you don't want to move the method and don't want to make it public you still have a couple of options to test it.

  • You can sometimes test a method through the public methods that call it. (Can be difficult sometimes because it is harder to control what is being passed to the method.)
  • You can write a public method which passes through to it, and prefix the name with "Test". (This is a bit hacky and should only ever be done with internal code that will not ever be in an API.)
  • You can change the method to protected and write a Test version of the class that inherits, and then exposes the method publicly on the test class. (This option works well because the test class can be kept with the tests so it doesn't dirty the production code. Only do this if you will not be subclassing this class already.)

Some people discourage testing private methods, because there really shouldn't be much logic in private methods that really needs to be tested. If it really needs tests it probably belongs in another class. My opinion is that if people are going to keep the code in the private method anyway, they might as well at least be testing it.

Structure your code how you like. Just don't let your classes get out of hand. If it becomes an issue then refactor it.

Friends don't let friends perform premature optimization.

PrematureOptimization

As Donald Knuth said, "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%."

I think it is safe to say this should apply to refactoring as well. Don't go on refactoring binges. Only refactor code you're currently working with.

Comments (3) -

  • 12/4/2008 2:13:33 PM | Reply

    This is probably classifiable as another hack, but you can also set the method to protected and use the InternalsVisibleTo attribute to allow your test assembly to see the protected method and let you skip the sub-classing.  


  • 12/8/2008 5:36:36 PM | Reply

    I'm a big fan of the protected method, and subclassing for the test class where I can get away with it.  It doesn't even feel like (too much) of a hack, since there could conceivably be situations where you are trying to derive from the class and want that method to be available (I still have a guilt trip and change them back to private sometimes Smile )


  • Brendan Enrick

    12/9/2008 9:34:56 AM | Reply

    Yeah I get guilt trips about some hacks. This one doesn't bug me too much, because I keep the testable child class of the class in a test assembly.


Loading