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 –
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.
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 –
- PrivateAccessor.invoke (Object, String, Class [], Object [])
- 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>
<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.
Reference - http://junit-addons.sourceforge.net/junitx/util/PrivateAccessor.html
http://www.artima.com/weblogs/viewpost.jsp?thread=132358
http://www.artima.com/weblogs/viewpost.jsp?thread=132358
dp4j offers an even simpler solution. Check it out.
ReplyDeleteHi Gabriele,
ReplyDeleteI 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.