JUnit is a widely used open-source testing framework for Java applications. It provides a simple and effective way to write unit tests, ensuring the reliability and correctness of our code. With JUnit, we can define assertions and test cases to verify the expected behavior of individual units of code, such as classes or methods.
For JUnit, private methods refer to methods declared as private within a Java class and intended to be used internally by that class. Private methods are not directly accessible or testable from JUnit test cases since they are considered implementation details and are not part of the public API. While JUnit does not provide direct mechanisms to test private methods, there are alternative approaches, like using reflection or extracting private functionality into separate methods that can be tested indirectly.
Java's reflection API allows us to access and invoke private methods dynamically. We can use reflection in our test methods to access and invoke the private methods of the class we want to test.
package io.educative.junit5;import org.junit.jupiter.api.Test;import java.lang.reflect.Method;import static org.junit.jupiter.api.Assertions.assertEquals;class PrivateClassTest {class TestClass {private int privateMethodName(int number) {System.out.println(number + 10);return number + 10;}}@Testvoid testPrivateMethod() throws Exception {TestClass TestClass = new TestClass();Method privateMethod = TestClass.class.getDeclaredMethod("privateMethodName", int.class);privateMethod.setAccessible(true);int result = (int) privateMethod.invoke(TestClass, 10);assertEquals(20, result);}}
Line 6: We initialize the inner class TestClass
within PrivateClassTest
.
Line 7: We define a private method that takes an integer argument number
and returns an integer.
Lines 8–10: We print the sum of number
and 10
to the console. This line is used for demonstration purposes to show the output of the private method.
Line 15: The @Test
input indicates that the following method is a test case.
Line 16: Defines the test case method named testPrivateMethod
. It throws the Exception
class to handle any exceptions during test execution.
Line 18: We retrieve the privateMethodName
method from the TestClass
class using reflection. It uses getDeclaredMethod
to access a private method and specifies the method name and argument types.
Line 19: We enable access to the private method by setting its accessibility to true
since private methods are not directly accessible by default.
Line 20: We invoke the private method on the TestClass
instance using reflection. It passes TestClass
as the object on which the method is invoked and 10
as the argument to the method.
Line 21: We compare the result
value with the expected value of 20
using the assertEquals
method. If the values don't match, an assertion error will indicate failure.
Suppose the private method contains significant functionality that needs to be tested. In that case, we can consider extracting that functionality into a separate helper method and making it a package-private
(default access level) instead of private. This way, the helper method can be tested directly, and the private method can remain as a thin wrapper around it.
public class MathUtils {public int multiplyByTwo(int number) {return multiply(number, 2);}private int multiply(int a, int b) {return a * b;}}
Lines 1–4: The MathUtils
class contains two methods: multiplyByTwo
which is
a public method, and multiply
which is a private helper method used to perform the actual multiplication operation.
Lines 6–9: The multiplyByTwo
method calls the multiply
method internally, passing the input number and the value 2
as arguments. It returns the multiplication result, which is the input number multiplied by 2
.
Free Resources