To test a class that has private methods, fields, or inner classes, you can use different methods like reflection, helper classes, and test doubles to check their behavior.
In this blog, we will learn how to test a class that has private methods, fields, or inner classes in more detail.
Table of Contents:
- What are Private Methods, Fields, and Inner Classes in Java
- Methods to Test Classes with Private Methods, Fields, or Inner Classes
- Method 1: Use Public Methods(General Strategy, Best Practice)
- Method 2: Use Reflection in Java
- Method 3: Using Inner Classes for Testing Private Inner Classes
- Method 4: Use Package-Private Access
- Method 5: Use PowerMock
- Pros and Cons of Testing Private Methods, Fields, and Inner Classes in Java
- Pros of Testing Private Methods, Fields, and Inner Classes
- Cons of Testing Private Methods, Fields, and Inner Classes
- Conclusion
- How to Test Private Methods, Fields, and Inner Classes in Java – FAQs
What are Private Methods, Fields, and Inner Classes in Java
- Private Methods: Private methods are the methods that are only accessed within the class in which they are declared. They are used to encapsulate the functionality of the class. They can be used to break down the complex logic into smaller ones.
- Private Fields: Private fields are the variables that are only accessed within the class in which they are declared. They are used to store the internal state and data that should not be changed from outside the class. They help in encapsulation and prevent other external classes from directly using the internal state of an object.
- Inner Classes: Inner classes are the classes that are defined within another class. They are used to encapsulate a single class. Inner classes can access the private members of the outer class.
Methods to Test Classes with Private Methods, Fields, or Inner Classes
Testing a class that contains private methods, fields, or inner classes is a difficult task, but there are several methods that you can use. Some of them are:
- Use Public Methods
- Use Reflection
- Use Inner Classes for Testing Private Inner Classes
- Use Package-Private Access
- Use PowerMock
Method 1: Use Public Methods(General Strategy, Best Practice)
This is the easiest and most effective way to test the private methods. In this, the testing is done by indirectly testing through the public methods. Since private methods are usually used inside public methods, testing them publicly will automatically check if the private methods are working correctly or not.
Example:
done by indirectly testing through the public methods. Since private methods are usually used inside public methods, testing them publicly will automatically check if the private methods are working correctly or not.
Example:
Explanation:
In the above Java code, the Calculator class has a private method, add(int a, int b), which can not be used directly from the outside class. Due to which, the public method addNumbers(int x, int y) calls the private method and returns the result.
Method 2: Use Reflection in Java
Reflection is a feature in Java that allows you to look into a class and use its private members, even if they are hidden. It is used to read and change the private fields, call the private methods, and access private inner classes.
Example:
Output:
Explanation:
The above Java code uses Reflection to access and call a private method named add() from the Calculator class. It then uses the setAccessible method to unlock the private method, and then invokes it with parameters 5 and 10
Method 3: Using Inner Classes for Testing Private Inner Classes
If a class that has a class marked as private, you can not use it from outside. Hence, to test a private inner class, you can create a test class in the same folder to use it indirectly.
Example:
Output:
Explanation:
In the above Java code, the OuterClass has a private inner class with a private method getSecretMessage(). Since the inner class and its methods are private, they cannot be accessed by the outside class.
Method 4: Use Package-Private Access
In this method, the classes are only used by the classes that are present in the same packages, including the test classes also. It is a simple way to allow testing.
Example:
Output:
Explanation:
In the above Java code, the add() function is not private, so it can be used directly by the other classes in the same package, like the Main class. This will allow you to test or use it easily without making it public or using reflection.
Method 5: Use PowerMock
When you need to use the private methods in Java, PowerMock (with Mockito) is one of the most powerful tools. As the private methods cannot be used directly in the unit tests, PowerMock will allow us to overcome this problem.
Example:
Output:
Explanation:
The above Java code uses PowerMock’s Whitebox to use the private method add() in the Calculator class. The main() method creates an object of the Calculator class and calls add(5, 10), which prints the output 15. This method call helps to test private methods without changing the whole code.
Note: PowerMock is useful for testing the private, static, and final methods. While using it, one should ensure PowerMock and Mockito dependencies are added (you need to use the Maven project for this method).
Pros and Cons of Testing Private Methods, Fields, and Inner Classes in Java
Below are some of the key pros and cons of these testing strategies:
Pros of Testing Private Methods, Fields, and Inner Classes
- Ensures Complete Test Coverage:
By testing the private methods, fields, and inner classes, you always ensure that all the parts of the code are covered by the tests, even if they are not directly accessed by the public methods.
- Improved Debugging and Verification:
Testing private members allows you to verify the correctness of the class’s internal workings, which can help to detect bugs.
- Greater Flexibility in Testing:
Techniques like reflection or PowerMock give flexibility when testing code that is otherwise difficult to access.
You can keep the private methods, fields, and inner classes to maintain a well-encapsulated design of code
Cons of Testing Private Methods, Fields, and Inner Classes
Accessing the private methods and fields directly ( through reflection or PowerMock) can break the principle of encapsulation, which is against the rules of OOPs.
Techniques like reflection or PowerMock make the code complex, as to use these, we have to write an extra step in the code.
Techniques like reflection or PowerMock degrade the performance of the code, especially when used with large test suites. For example, reflection is slower than direct method calls, due to which the testing being slow.
Conclusion
The best way to test the private methods in Java is through the public methods that can use them, ensuring encapsulation also. If direct usage is needed for the class, techniques like reflection, package-private access, inner classes, or PowerMock can be used.
If you want to learn more about Java, you can refer to our Java Course.
How to Test Private Methods, Fields, and Inner Classes in Java – FAQs
Q1. Can private methods be tested in Java?
Yes, private methods can be tested in Java using methods like reflection, PowerMock, package-private access, or public methods that internally call them.
Q2. Is it necessary to test private methods?
No, it is not necessary to always test the private methods. Since private methods are internal to a class, they should be tested through the public methods that use them.
Q3. How can reflection be used to test private components?
Reflection allows accessing private methods dynamically using setAccessible(true).
Q4. Can we call a private method in a test class?
Yes, you can call a private method in a test class,
Q5. Are constructors public or private?
By default, constructors are defined in the public section of the class.