Testing Private Methods

Problem

You can’t test certain methods because they’re private and your test can’t get to them.

Solution

Refactor the functionality into standalone classes or make the methods package scope.

Discussion

Suppose you have the following code:

public class Widget {
    public void draw(Graphics g) {
        computeCoordinates(  );
        // paint the component
    }
    private void computeCoordinates(  ) {
        // some complex logic here
    }
}

The real complexity lies in the computeCoordinates( ) method, but tests cannot call the method directly because it is private. You could write tests against the draw( ) method, but such tests might be slow and would be more complicated than necessary. You might have to wait while the widget paints itself on screen, or you might have to create mock Graphics objects. Making the computeGraphics( ) method package-scope is a simple fix and makes it easy for tests in the same package to call the method. We use this approach in many of our classes and it works well.

Increasing visibility in order to facilitate testing is not without drawbacks. Good designs seek to minimize visibility of fields and methods. By making this method package-scope, any other class in the same package can now call it. This can increase coupling and increase overall application complexity. While we find ourselves using this technique from time to time, it is often an indicator that something needs changing in the design.

Warning

Hard-to-test code is a “smell” suggesting that the design can be improved. ...

Get Java Extreme Programming Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.