Updated April 6, 2023
Introduction to Java Testing Private Methods
The java testing private methods are defined as the methods having private access modifier and are restricted to be accessed in the defining class only and are not visible in their child class due to which are not eligible for overridden, however, we can define a method with the same name in the child class and could access in parent class, also can test the private methods by making private methods package access which allows we to test them directly with JUnit from the test classes in the same package but the testing of private methods in SuiteRunner is easier than to test in JUnit.
List of Four basic Approaches of Testing Private Methods
Whether you are using JUnit or SuiteRunner we have four basic approaches to testing private methods,
1. Do not test private methods (Indirect testing)
Sometimes the private method is doing a very complicated task and the test should be tested very well so we do not want that the users will have access to these methods for that the private methods need to be protected.
The private methods could not test indirectly but only their effect on the public methods that call them. Testing private methods may be an indication that those methods are moved into another class that assisting/supporting the reusability.
If we extract the private method from which are already working and has good unit test coverage then which already exists in a unit test that enough to test so we do not need to write more unit test for the private methods. But if we want to write the private method before its calling method and we want to write the unit tests before writing the private method.
Examples
public class testClass
{
private String testMethod(String s)
{
return s;
}
}
The above sample example is only for testing private methods. If we have a class ‘testClass’ then it is called by a method as ‘testMethod( )’, then that method is private and by passing string or object we can return the value.
2. Give the method package access
Giving method package access is works fine to testing private methods with JUnit but it is slightly costly. When a method having private access modifier then it is part of the implementation of the class. We can ignore the method if we just trying to use a class from another class in the package and we can figure out this by using the package access method. Also, the testing of non-public methods of classes can be done by using the method access package.
The first way to make the method package private with no access modifier and put tests into the same package, this is a common way but still, if we want another code then the second way is to make the method public.
3. Use a nested test class
The third thing about testing private methods in java is the use of nested test class, it can be done by nesting a static class inside the production class being tested. The nested class has access to the private member of its enclosing class, it would be able to invoke the private methods directly. The static class itself could be package access, allowing it to be a load part of the white box test.
The downside of this nested test class is that, if we don’t want the nested class being accessible in our department JAR file, then we need to do extra work to extract it. This may be problematic because quality analysts will make changes in source code.
4. Use reflection
Now come towards the next use of reflection. The advantage of using reflection to testing private methods is that it provides a clean separation of test code and production code. As we already see in the nested class approach that the tests need not be tested inside the class, in which the class is under test but they can be placed alongside the other tests that exercise the package level and public methods of the class. As we use nested class then we do not need to add any extra nested class at the package access level.
Reflection is an API that is used to examine or modify the behavior of the methods, classes, interfaces at run time. The disadvantage of the use of reflection is that the test code is far more tedious because it uses the reflection API.
Example: Java program to describe the use of reflection
Code:
import java.lang.reflect.Method;
import java.lang.reflect.Field;
class Test
{
private String s;
public Test()
{
s = "Java Testing Methods";
}
public void method1()
{
System.out.println("The string is " + s);
}
public void method2(int n)
{
System.out.println("The number is " + n);
}
private void method3()
{
System.out.println("Private method invoked");
}
}
class Reflect
{
public static void main(String args[]) throws Exception
{
Test obj = new Test();
Class cls = obj.getClass();
System.out.println("The name of class is " +
cls.getName());
System.out.println("The public methods of class are : ");
Method[] methods = cls.getMethods();
for (Method method:methods)
System.out.println(method.getName());
Method methodcall1 = cls.getDeclaredMethod("method2",
int.class);
methodcall1.invoke(obj, 19);
Field field = cls.getDeclaredField("s");
field.setAccessible(true);
field.set(obj, "JAVA");
Method methodcall2 = cls.getDeclaredMethod("method1");
methodcall2.invoke(obj);
Method methodcall3 = cls.getDeclaredMethod("method3");
methodcall3.setAccessible(true);
methodcall3.invoke(obj);
}
}
Output:
In the above java program, first, we have to import java.lang packages then created a private field in the class, the constructor also created. The method1() has been taken as a public method with no arguments then created method2() also a public method but with integer arguments and private method method3 has been revoked and the above three methods called in Reflect class and the out is given in above screenshot.
Conclusion
In this article, we conclude that we should not test the private methods directly, but only their effects on the public methods that call them. Also, we get concluded that the test should only be accessing the class’s public interface. If we test private methods then arrange the reflective code into the private static class.
Recommended Articles
This is a guide to Java Testing Private Methods. Here we discuss the Introduction, four basic approaches to testing private methods, for example with code implementation. You may also have a look at the following articles to learn more –