Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception when configuring expectations on method returning enum with abstract methods on JDK17 #722

Open
adessaigne opened this issue Mar 9, 2022 · 1 comment

Comments

@adessaigne
Copy link

adessaigne commented Mar 9, 2022

Hello,

In the following environment:

  • JMockit 1.49
  • Code built and tested using OpenJDK 17.0.2

When testing the following code

public class ServiceTest {
    public enum Flag {
        ENABLED {
            @Override
            Flag flip() {
                return DISABLED;
            }
        },

        DISABLED {
            @Override
            Flag flip() {
                return ENABLED;
            }
        };

        abstract Flag flip();
    }

    public interface Service {
        Flag flag();
    }

    @Mocked
    Service m_service;

    @Test
    public void shouldWork() {
        new Expectations() {{
            m_service.flag();
            result = Flag.ENABLED;
        }};

        System.out.println(m_service.flag());
    }
}

We have the following exception

java.lang.IncompatibleClassChangeError: class demo.$Subclass_Flag_flag cannot inherit from sealed class demo.ServiceTest$Flag
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:874)
	at demo.ServiceTest$1.<init>(ServiceTest.java:38)
	at demo.ServiceTest.shouldWork(ServiceTest.java:37)

It fails because it tries to mock the enum. Is there a way to say "do not try to mock the result, I will provide it to you"? Thank you

@adessaigne
Copy link
Author

Here is a dirty hack I've found that works around this issue

public static <T> void setJMockitDefaultValue(Class<T> aClass, T defaultValue) {
    requireNonNull(aClass, "The class must be defined");
    requireNonNull(defaultValue, "The default value must be defined");

    try {
        final Field field = DefaultValues.class.getDeclaredField("TYPE_DESC_TO_VALUE_MAP");
        field.setAccessible(true);
        final Map<String, Object> map = (Map<String, Object>) field.get(null);
        map.put(aClass.descriptorString(), defaultValue);
    } catch (Exception e) {
        throw new RuntimeException("Cannot initialize JMockit properly", e);
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant