Search code examples
javamockingjmockit

JMockit mocking a class that throws an exception during initialisation


I've been trying to create a mock of a oracle.adf.share.security.identitymanagement.UserProfile for example

@Test
public void testMyTest(@Mocked final UserProfile userProfile) {
    new Expectations() {
        {
           userProfile.getBusinessEmail();
           result = "me@me.com";
        }
    };

    unitUnderTest.methodUnderTest();
}

What I'm finding however is that an exception is thrown when JMockit tries to construct the mock

java.lang.ExceptionInInitializerError
  at java.lang.Class.forName0(Native Method)
  at java.lang.Class.forName(Class.java:247)
  at oracle.jdevimpl.junit.runner.junit4.JUnit4Testable.run(JUnit4Testable.java:24)
  at oracle.jdevimpl.junit.runner.TestExecution.run(TestExecution.java:27)
  at oracle.jdevimpl.junit.runner.JUnitTestRunner.main(JUnitTestRunner.java:88)
Caused by: oracle.adf.share.security.ADFSecurityRuntimeException: EXC_FAILED_ID_STORE
  at oracle.adf.share.security.identitymanagement.UserManager.<init>(UserManager.java:111)
  at oracle.adf.share.security.identitymanagement.UserManager.<init>(UserManager.java:83)
  at oracle.adf.share.security.identitymanagement.UserProfile.<clinit>(UserProfile.java:62)

After decompiling the UserProfile I can see it has something like this

public class UserProfile implements Serializable {
    ...
    private static UserManager _usrMgr = new UserManager();
    ...
}

The UserManager constructors look like this

public UserManager() {
    this((String) null);
}

public UserManager(String providerClassName) {
    if (providerClassName != null) {
        ...
    } else { 
        String clzName = ADFSecurityUtil.getIdentityManagementProviderClassName();
        if (clzName != null) {
            IdentityManagement provider = (IdentityManagement) createObject(clzName);
            setIdentityManagementProvider(provider);
        } else {
            throw new ADFSecurityRuntimeException("EXC_FAILED_ID_STORE");
        }
    }
}

Now I could set up an Expectation to return something when ADFSecurityUtil.getIdentityManagementProviderClassName(); is called but then I foresee further issues when it tries to load this class.

What's the best way to solve this issue?


Solution

  • Ok so I managed to find a solution Fakes! Here's what I did

    @Test
    public void testMyTest() {
        new Mockup<UserProfile>() {
            @Mock
            public void $cinit() {
                // do nothing
            }
    
            @Mock
            public String getBusinessEmail() {
                return "me@me.com";
            }
        };
    
        unitUnderTest.methodUnderTest();
    }