2

I have legacy code where is private enum which I need to construct another type for acceptance testing, but I'm stuck because this enum is private and it is not part of any class, looks like following:

enum Element {
    ELEMENT1, ELEMENT2;

    public static Element[] values() { /* compiled code */ }

    public static Element valueOf(java.lang.String name) { /* compiled code */ }

    private Element() { /* compiled code */ }
}

is there a way how to use this enum, expose it from legacy code, or maybe way how to mock it?

Update: I know I can read values enums by reflection, but I have another class which is public and I need to use enum value in its constructor, this class is in the same package like Element, its constructor is :

public class ElementProvider {
   public ElementProvider(string name, Element element){ /*compiled code*/ }
} 
Martin Bodocky
  • 651
  • 1
  • 5
  • 16
  • Is it private? Where is it defined? As per above code it's package default. [read more...](http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html) – Braj Aug 01 '14 at 08:59
  • 1
    @user3218114 Look likes package-private. Well, I think reflection is the only way here – Leri Aug 01 '14 at 09:00
  • Yes it's package-private, how can I reach enum which is not part of any class by reflection? Basically I know just namespace. – Martin Bodocky Aug 01 '14 at 09:06
  • possible duplicate of [What's the proper way to test a class with private methods using JUnit?](http://stackoverflow.com/questions/34571/whats-the-proper-way-to-test-a-class-with-private-methods-using-junit) – Raedwald Aug 01 '14 at 09:14
  • See also http://stackoverflow.com/questions/24497765/accessing-inner-enum-in-another-class-for-testing – Raedwald Aug 01 '14 at 09:27

1 Answers1

7

A way to do it could be to use Class.forName and load it using the package + name.

For example:

Class<?> enumElement = Class.forName("com.my.package.Element");

Then if everything is OK you will have the enum.

Then with getEnumConstants you can read all constants of the enum (you can check if it's an enum using isEnum if needed):

Object[] enumElements = elements.getEnumConstants();

for (Object obj : enumElements) {
    System.out.println(obj);
}

You are forced to use Object since you don't know what type it will be (well, you know but you can't access it)

And use enumElements[0] to access ELEMENT1 and so on.


About your updated question, that's the first thing that comes in my mind:

Class<?> enumElement = Class.forName("org.myname.test.Element");
Object[] enumElements = elements.getEnumConstants();

Object element1 = enumElements[0];

ElementProvider elementProvider = ElementProvider.class.getDeclaredConstructor(String.class, enumElement).newInstance("Hello", element1);
Marco Acierno
  • 14,682
  • 8
  • 43
  • 53