Am trying to obtain and invoke a protected method residing in a different class and also different package using Java Reflection.
Class containing protected method:
package com.myapp; public class MyServiceImpl { protected List<String> retrieveItems(String status) { // Implementation } }
Calling class:
package xxx.myapp.tests; import com.myapp.MyServiceImpl; public class MyTestCase { List<String> items; public void setUp() throws Exception { MyServiceImpl service = new MyServiceImpl(); Class clazz = service.getClass(); // Fails at the next line: Method retrieveItems = clazz.getDeclaredMethod("retrieveItems"); // How to invoke the method and return List<String> items? // tried this but it fails? retrieveItems.invoke(clazz, "S"); } }
The compiler throws this Exception:
java.lang.NoSuchMethodException: com.myapp.MyServiceImpl.retrieveItems()
The easiest way would be to make sure your tests are in the same package hierarchy as the class you are testing. If that's not possible then you can subclass the original class and create a public accessor that calls the protected method.
The protected access modifier is accessible within the package. However, it can also accessible outside the package but through inheritance only. We can't assign protected to outer class and interface. If you make any constructor protected, you cannot create the instance of that class from outside the package.
For this kind of testing, you don't care about visibility, interfaces, or any of that, you only care about having working code. So yes, you would test private and protected methods if you felt they needed to be tested for you to answer Yes to the question.
Protected Access Modifier: Variables, methods and constructors which are declared protected in a superclass can be accessed only by the subclasses in other package or any class within the package of the protected members' class. The protected access modifier cannot be applied to class and interfaces.
The problem with your code is that the getDeclaredMethod
function looks up a function both by name and by argument types. With the call
Method retrieveItems = clazz.getDeclaredMethod("retrieveItems");
The code will look for a method retrieveItems()
with no arguments. The method you're looking for does take an argument, a string, so you should call
Method retrieveItems = clazz.getDeclaredMethod("retrieveItems", String.class);
This will tell Java to search for retrieveItems(String)
, which is what you're looking for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With