I have an enum that contains an non-public abstract method and I can not change the visibility of this abstract method. The abstract method is implemented for every single unit inside the enum.
I am trying to access this method from another package for the purposes of unit testing, but I can not because it is not visible in the other package. Is there a way where I can create a getter method for an abstract method?
Is there a different way to do the unit test in a way that does not involve using a getter method or changing the visibility of the abstract method?
Here is an example of the code I am working with:
public enum random { A{ someFunction() { System.out.println("A"); } } B{ someFunction() { System.out.println("B"); } } C{ someFunction() { System.out.println("C"); } } abstract void someFunction(); };
Advertisement
Answer
There are two ways you can do this. One way, like you suggested in your question, is to use a public method to expose your package-private method. Here’s a short example of such a program:
public enum MyEnum { A { @Override void someFunction() { System.out.println("A"); } }, B { @Override void someFunction() { System.out.println("B"); } }, C { @Override void someFunction() { System.out.println("C"); } }; abstract void someFunction(); public void someFunctionPublic() { // Here I'm just calling the package-private method from a public method: someFunction(); } }
public class Other { public static void main(String[] args) { // Here I call my public method: MyEnum.A.someFunctionPublic(); } }
Output will be:
A
The other way is to use something called reflection. You mentioned that you wanted a way to access the method without creating a getter method. This is how you can do just that:
// This is exactly how you had it, no changes: public enum MyEnum { A { @Override void someFunction() { System.out.println("A"); } }, B { @Override void someFunction() { System.out.println("B"); } }, C { @Override void someFunction() { System.out.println("C"); } }; abstract void someFunction(); }
public class Other { // Note the throws clauses, this is important because I call methods that throw checked exceptions: public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { // Get a handle on the method: Method method = MyEnum.class.getDeclaredMethod("someFunction"); // Set it to be accessible (since you specified it to be package-private): method.setAccessible(true); // Invoke it using the implementation in MyEnum.A: method.invoke(MyEnum.A); } }
Output will be:
A
Please note that reflection can get out of hand quite quickly, especially if you start renaming methods and/or changing the method headers. Useful for testing, yes, but I would keep it out of production code. Also, a small terminology thing, you refer to “methods” as “functions” in your question. A method is a function that belongs to an Object, so since Java is entirely object-oriented, there are no functions in Java.