Testing private methods using JUnit is a tricky thing. We have different ways to do so, but I feel using reflection is the better way of doing things. Below is a utility class which invokes the private methods using reflection and return the expected results from the private method.
Calculator.java
package com.dev.junit.test;
public class Calculator {
private int privateField = 0;
private Integer calculateSimpleInterest(Integer principal, Integer term, Integer rateOfInterest){
Integer interest = principal*term*rateOfInterest/100;
return interest;
}}
PrivateUtility.java
package com.dev.junit.test;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class PrivateUtility {
public static Object invokePrivate(String methodName, Object object, Class[] signature, Object[] values)
throws NoSuchMethodException
{
Class pvtClass = object.getClass();
Method method = null;
while (method == null) {
try {
method = pvtClass.getDeclaredMethod( methodName, signature );
} catch (NoSuchMethodException e) {
pvtClass = pvtClass.getSuperclass();
if (pvtClass == null) {
throw e;
}
}
}
method.setAccessible(true);
try {
return method.invoke(object, values );
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new NoSuchMethodException( e.toString() );
} catch (InvocationTargetException e) {
e.printStackTrace();
throw new RuntimeException( e.getCause() );
}
}
public static void setPrivate(Object object, String fieldName, Object value)
throws NoSuchFieldException
{
try {
Field field = null;
Class instanceClass = object.getClass();
while (field == null) {
try {
field = instanceClass.getDeclaredField( fieldName );
} catch (NoSuchFieldException e) {
instanceClass = instanceClass.getSuperclass();
if (instanceClass == null) {
throw e;
} } }
field.setAccessible(true);
field.set(object, value);
} catch (SecurityException e) {
e.printStackTrace();
throw new NoSuchFieldException( "Unable to set field [" + fieldName + "]: " + e.toString() );
} catch (IllegalArgumentException e) {
e.printStackTrace();
throw new NoSuchFieldException( "Unable to set field [" + fieldName + "]: " + e.toString() );
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new NoSuchFieldException( "Unable to set field [" + fieldName + "]: " + e.toString() );
}
}
public static Integer getPrivate(Object object, String fieldName )
throws NoSuchFieldException
{
try {
Class instanceClass = object.getClass();
Field field = null;
while (field == null) {
try {
field = instanceClass.getDeclaredField( fieldName );
} catch (NoSuchFieldException e) {
instanceClass = instanceClass.getSuperclass();
if (instanceClass == null) {
throw e;
} } }
field.setAccessible(true);
return (Integer) field.getInt(object);
} catch (SecurityException e) {
e.printStackTrace();
throw new NoSuchFieldException( "Unable to access field [" + fieldName + "]: " + e.toString() );
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new NoSuchFieldException( "Unable to access field [" + fieldName + "]: " + e.toString() );
}
}}
CalculatorPrivateTest.javaimport java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class PrivateUtility {
public static Object invokePrivate(String methodName, Object object, Class[] signature, Object[] values)
throws NoSuchMethodException
{
Class pvtClass = object.getClass();
Method method = null;
while (method == null) {
try {
method = pvtClass.getDeclaredMethod( methodName, signature );
} catch (NoSuchMethodException e) {
pvtClass = pvtClass.getSuperclass();
if (pvtClass == null) {
throw e;
}
}
}
method.setAccessible(true);
try {
return method.invoke(object, values );
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new NoSuchMethodException( e.toString() );
} catch (InvocationTargetException e) {
e.printStackTrace();
throw new RuntimeException( e.getCause() );
}
}
public static void setPrivate(Object object, String fieldName, Object value)
throws NoSuchFieldException
{
try {
Field field = null;
Class instanceClass = object.getClass();
while (field == null) {
try {
field = instanceClass.getDeclaredField( fieldName );
} catch (NoSuchFieldException e) {
instanceClass = instanceClass.getSuperclass();
if (instanceClass == null) {
throw e;
} } }
field.setAccessible(true);
field.set(object, value);
} catch (SecurityException e) {
e.printStackTrace();
throw new NoSuchFieldException( "Unable to set field [" + fieldName + "]: " + e.toString() );
} catch (IllegalArgumentException e) {
e.printStackTrace();
throw new NoSuchFieldException( "Unable to set field [" + fieldName + "]: " + e.toString() );
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new NoSuchFieldException( "Unable to set field [" + fieldName + "]: " + e.toString() );
}
}
public static Integer getPrivate(Object object, String fieldName )
throws NoSuchFieldException
{
try {
Class instanceClass = object.getClass();
Field field = null;
while (field == null) {
try {
field = instanceClass.getDeclaredField( fieldName );
} catch (NoSuchFieldException e) {
instanceClass = instanceClass.getSuperclass();
if (instanceClass == null) {
throw e;
} } }
field.setAccessible(true);
return (Integer) field.getInt(object);
} catch (SecurityException e) {
e.printStackTrace();
throw new NoSuchFieldException( "Unable to access field [" + fieldName + "]: " + e.toString() );
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new NoSuchFieldException( "Unable to access field [" + fieldName + "]: " + e.toString() );
}
}}
package com.dev.junit.test;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class CalculatorPrivateTest {
@Test
public void testCalculateSimpleInterest(){
Calculator calc = new Calculator();
try {
// invoke private method with object parameters
Object obj = PrivateUtility.invokePrivate("calculateSimpleInterest", calc, new Class[]{Integer.class,Integer.class,Integer.class}, new Object[]{1000,10,12});
int i = (Integer)obj;
assertEquals(1200, i);
// invoke private method with object parameters
Object obj1 = PrivateUtility.invokePrivate("calculateSimpleInterestPrimitives", calc, new Class[]{Integer.TYPE,Integer.TYPE,Integer.TYPE}, new Object[]{2000,10,12});
int i1 = (Integer)obj1;
assertEquals(2400, i1);
//set the value to private fields
PrivateUtility.setPrivate(calc, "privateField", 200);
//check the value to private fields
int pvtValue = (Integer)PrivateUtility.getPrivate(calc, "privateField");
assertEquals(200, pvtValue);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}catch (NoSuchFieldException e) {
e.printStackTrace();
}
} }
No comments:
Post a Comment