Blog

23 Jan, 2009

Unit testing private methods in Java

Posted by: admin In: Programming

Want to unit test a private method in Java?

You could obviously change your methods access modifier from private. By making it public you’re breaking encapsulation and by making it protected you’re making your API less intuitive. Don’t do that.

Another way to go about this is to create a new class that’s extending the one with your private method

I find the easiest and most convenient way achieve unit testing of private methods is reflection. Some of the features the Java reflection API offers is access to private fields and invocation of private methods. This sounds like something useful for our problem, by using reflection we’re able to test our private methods without making any changes to our classes.

class TestSubject {
 
	/**
	 * For some reason we want to unit-test this method
	 */
	private int adder(int numberOne, int numberTwo) {
		int answer = numberOne + numberTwo;
		return answer;
	}
}

This is the method we want to test, here is how we go around to actually do it:

TestSubject subjectInstance = new TestSubject();
Class testClass = subjectInstance.getClass();
 
// Find the method. getDeclaredMethod will give you any methods from that
// class whether it's public or not where getMethod only will give you
// methods with public access. The first argument is obviously our method's name,
// where the next arguments are the formal types of the adder methods parameters.
Method adderMethod = testClass.getDeclaredMethod("adder", int.class, int.class);
 
// Method is a sub class of AccessibleObject if we don't call it's
// setAccessible method we'll get an IllegalAccessException when we
// try to invoke it on our object.
adderMethod.setAccessible(true); 
 
// Invoke the method on our instance of TestSubject
int answer = (Integer) adderMethod.invoke(subjectInstance, 2, 2); 
 
// assert answer = 4

It’s more or less just to plug it into your testing framework of choice and you’ll have unit testing of your private methods.

But hey! Do you really want to unit test your private methods? Doesn’t it give you that bad feeling in your stomach. You know the feeling you get when you’re code smells a little? I mean, a part of the reason for those methods being private is that they’re subject to change.

It’s the oldest oo rule in the book, hide the inner working of you’re classes so you later can change the inner workings of the class without exposing any change to your clients. What you really want to do is to unit test the public methods using those private once. If you find that difficult it might be a little hint that you should consider changing your design a little in order to improve it’s testability.

Why did I bother showing you how to unit test private methods if I consider it bad practice? Well, sometimes when I’m working on complicated things I like to unit-test private methods while working on the class. And there might be situations where unit testing of private methods is the right way to go. Just be careful so you’re not writing a lot of tests you’ll waste a lot of time maintaining later!

Relevant Java API: Class, Method and reflect.

Happy coding!

No Responses to "Unit testing private methods in Java"

Comment Form