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.