9

Note that this is a UNIT test, not an integration test so I don't want any Spring and literally everything that can be mocked, should be.

This code:

@RunWith(PowerMockRunner.class)
@PrepareForTest({...})
@PowerMockIgnore({
        "com.sun.crypto.*",
        "javax.crypto.*",
        "javax.management.*"})
public class TestClass {
...


@Test
public void testMethod (
          Authentication mockAuthentication = Mockito
                .mock(Authentication.class);  
  ) 
}

...throws this exception:

java.lang.LinkageError: loader constraint violation: loader (instance of org/powermock/core/classloader/MockClassLoader) previously initiated loading for a different type with name "javax/security/auth/Subject"

    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at org.powermock.core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:262)
    at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:206)
    at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass1(DeferSupportingClassLoader.java:89)
    at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:79)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at org.springframework.security.authentication.TestingAuthenticationToken$MockitoMock$2107019845.<clinit>(Unknown Source)
    at sun.reflect.GeneratedSerializationConstructorAccessor27.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:48)
    at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
    at org.mockito.internal.creation.instance.ObjenesisInstantiator.newInstance(ObjenesisInstantiator.java:18)
    at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.createMock(SubclassByteBuddyMockMaker.java:47)
    at org.powermock.api.mockito.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:50)
    at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:35)
    at org.mockito.internal.MockitoCore.mock(MockitoCore.java:63)
    at org.mockito.Mockito.mock(Mockito.java:1729)
    at org.mockito.Mockito.mock(Mockito.java:1642)

Clue? I've been trying various things from StackOverflow but haven't found a solution yet. Surely PowerMockito uses this class to work it's magic, so maybe this is loaded by PowerMockito and cannot be changed?

  • No. It's a typical scenario where someone has written a prototype and then the company refuses to throw it away because they don't understand engineering. Then because a prototype itself is a test, the code which was never meant to be tested has to be tested. If you re-factor for testing before testing, you introduce bugs because the code is not tested. We've decided to use powermock before refactoring everything just to get us to state of decent coverage. The plan is to remove it later. It will not be used in new code. – user447607 Jun 24 '18 at 12:56

1 Answers1

12

In that case, the class are not load belongs to javax.security, thus you should ignore "javax.security.*" in @PowerMockIgnore. It works.

Gustavo Santos
  • 121
  • 1
  • 3