Monday, April 2, 2012

Unit Testing the private methods in Java


It very common situation, where we create proper encapsulated classes, and then think how to unit test private methods.

We can tackle the situation in the following ways –
1.      Testing from the less restrictive methods available in the class.
2.      Breaking the encapsulation by changing to less restrictive access and test
3.      Test by bypassing Java modifier security in our unit test.

As the first two approaches are self explanatory, I will jump to third approach “Unit test by bypassing the java modifier security in our unit test”.

There is an open source library called JUnitAddons, which provide multiple utilities to help us in unit testing the component. One of these is PrivateAceessor.

PrivateAccessor is a class, which provides us the necessary functions to bypass the java security in our unit tests. We can use it’s invoke method to access the protected, default or private methods, which might not be accessible without bypassing java modifier security.

Its syntaxes are as mentioned below –

  1. PrivateAccessor.invoke (Object, String, Class [], Object [])
  2. PrivateAccessor.invoke (Class, String, Class [], Object [])

Sample Use
1.      PrivateAccessor.invoke (ObjectContanigFunction, “methodName”, parameterTypeArray, parameters)
2.      PrivateAccessor.invoke (ClassContanigFunction, “methodName”, parameterTypeArray, parameters)

We can easily use JUnitAddons by adding below mentioned maven dependency in our project.
        <dependency>
                 <artifactId>junit-addons</artifactId>
                 <groupId>junit-addons</groupId>
                   <version>1.4</version>
        </dependency>

Sample code example is as mentioned below -

PrivateMethodClass - Class having factorial method, which is private

public class PrivateMethodClass {
	private static int getFactorialOf(Integer integerNumber) {
		return integerNumber==0?1:integerNumber * getFactorialOf(integerNumber - 1);
	}
}

PrivateMethodTest - Class testing the factorial method defined in the above 

import junit.framework.TestCase;
import junitx.util.PrivateAccessor;
import org.junit.Test;

public class PrivateMethodTest extends TestCase{

	@Test
	public void test() throws Throwable{
		assertEquals(6, PrivateAccessor.invoke(PrivateMethodClass.class,"getFactorialOf",new Class[] {Integer.class} ,new Object[]{new Integer(3)}));
	}
}

I personally prefer using PrivateAccessor than other two methods mentioned above. Because it provides deep control on testing without breaking encapsulation.



2 comments:

  1. dp4j offers an even simpler solution. Check it out.

    ReplyDelete
  2. Hi Gabriele,

    I think, PrivateAccessor in junit-addons is better than dp4j because junit-addons can be used with any editor including eclipse. While dp4j can not be used in all the editors.

    I think, editor support is one of the most important feature required to improve maintainability and usability of any library/framework,which is missing in dp4j.

    ReplyDelete