2013-05-13 3 views
86

나는 이러한 코드있어 동안 : 내가 가진이 테스트를 실행하는 동안Mockito + PowerMock LinkageError가 조롱 시스템 클래스

@RunWith(PowerMockRunner.class) 
@PrepareForTest({Thread.class}) 
public class AllMeasuresDataTest { 

@Before 
public void setUp() throws Exception { 
} 

@Test 
public void testGetMeasures() { 
    AllMeasuresData measure = new AllMeasuresData(); 
    assertEquals(measure.getMeasures(), null); 
    HashMap<String, Measure> map = new HashMap<String, Measure>(); 
    measure.setMeasures(map); 
    assertEquals(measure.getMeasures(), map); 
    measure.setMeasures(null); 
    assertEquals(measure.getMeasures(), null); 
} 

@Test 
public void testAllMeasuresData() throws IOException { 
    ClassLoader loader = PowerMockito.mock(ClassLoader.class); 
    Thread threadMock = PowerMockito.mock(Thread.class); 
    Vector<URL> vec = new Vector<URL>(); 
    Mockito.when(loader.getResources("measure")).thenReturn(vec.elements()); 
    Mockito.when(threadMock.getContextClassLoader()).thenReturn(loader); 
    PowerMockito.mockStatic(Thread.class); 
    Mockito.when(Thread.currentThread()).thenReturn(threadMock); 
     ... 
    } 
} 

을 :

java.lang.LinkageError: loader constraint violation: loader (instance of org/powermock/core/classloader/MockClassLoader) previously initiated loading for a different type with name "javax/management/MBeanServer" 
at java.lang.ClassLoader.defineClass1(Native Method) 
at java.lang.ClassLoader.defineClass(ClassLoader.java:791) 
at java.lang.ClassLoader.defineClass(ClassLoader.java:634) 
at org.powermock.core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:201) 
at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:149) 
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:67) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:356) 
at org.codecover.instrumentation.java.measurement.ProtocolImpl.initializeMBean(ProtocolImpl.java:247) 
at org.codecover.instrumentation.java.measurement.ProtocolImpl.<init>(ProtocolImpl.java:237) 
at org.codecover.instrumentation.java.measurement.ProtocolImpl.getInstance(ProtocolImpl.java:185) 
at measure.CodeCoverCoverageCounter$6ya5ud0ow79ijrr1dvjrp4nxx60qhxeua02ta2fzpmb1d.<clinit>(MeasureCalculatorsHolder.java:146) 
at measure.MeasureCalculatorsHolder.<clinit>(MeasureCalculatorsHolder.java:17) 
at java.lang.Class.forName0(Native Method) 
at java.lang.Class.forName(Class.java:188) 
at javassist.runtime.Desc.getClassObject(Desc.java:43) 
at javassist.runtime.Desc.getClassType(Desc.java:152) 
at javassist.runtime.Desc.getType(Desc.java:122) 
at javassist.runtime.Desc.getType(Desc.java:78) 
at algorithm.AllMeasuresDataTest.testGetMeasures(AllMeasuresDataTest.java:26) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:601) 
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:66) 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:312) 
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:86) 
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:94) 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:296) 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit49RunnerDelegateImpl$PowerMockJUnit49MethodRunner.executeTestInSuper(PowerMockJUnit49RunnerDelegateImpl.java:116) 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit49RunnerDelegateImpl$PowerMockJUnit49MethodRunner.executeTest(PowerMockJUnit49RunnerDelegateImpl.java:77) 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:284) 
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:84) 
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49) 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:209) 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:148) 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:122) 
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34) 
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44) 
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:120) 
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:101) 
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53) 
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53) 
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
at org.codecover.juniteclipse.runner.EclipseTestRunner.main(EclipseTestRunner.java:40) 

당신은 내가 못하게하려면 어떻게 알아? 시험의 대상이 아닌 Thread.class있는 클래스를 준비, 모의 시스템 클래스에

ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
... 
Enumeration<URL> resources = classLoader.getResources(path); 
+0

모의 시도는 무엇입니까? 그리고 왜? – NilsH

+0

첫 번째 테스트는 getters 및 setters 테스트입니다. 거기에서 생성자를 호출합니다 (예외가 발생합니다). 두 번째는 생성자 테스트입니다. 세 번째 코드 스 니펫에 포함 된 리소스 열거를 제어하려고합니다. –

+1

우선, 테스트 결과가 구현과 매우 밀접하게 관련되어 있다고 생각합니다. 경험에 의하면 이것은 깨지기 쉬운 테스트로 이어질 것입니다. 우선, 테스트를 작성할 때 "블랙 박스"를 생각하고 싶습니다. "이 코드가 어떻게 작동하는지"보다는 "이 코드 조각이 무엇인가"입니다. 둘째로, 나는 당신이 자원의 집합을 만들고 자바 런타임이 클래스 로딩 자체를 다루도록하는 것이 더 낫다고 생각한다. – NilsH

답변

236

시도 :

@PowerMockIgnore("javax.management.*")

나를 위해 일했다.

+2

Woot woot! - 그게 전부예요 ;-) –

+2

정밀도 * "테스트 클래스". 간단하고 유용한 답변! – pdem

+1

고마워요 –

3

위해 : 나는 어쩌면 이러한 코드 조각을 조롱하는 또 다른 방법이있다. PowerMock은 계기가 될 수있는 방법이 없습니다. Thread.class은 PowerMock이 계측하기 훨씬 전에 JVM을 시작하는 동안 필요하기 때문입니다.

계측기가 작동하는 방식으로, 일단 클래스가로드되면 더 이상 계측 할 수 없습니다.

the PowerMock wiki을 참조하십시오. 테스트 클래스에이 주석을 추가

20

클래스 로더 충돌이 사용 @PowerMockIgnore("javax.management.*")

모의 클래스 로더 그것은 작동 javax.*. 를로드하지 않습니다 보자.

+0

'@PowerMockIgnore ("javax.management. *")'사용 후, 테스트 클래스는 단독으로 작동합니다. 하지만 ** 패키지 **에서 'Junit 테스트'로 실행하면 'ApplicationContext를로드하지 못했습니다.'오류가 발생합니다. 'org.apache.catalina.LifecycleException : 자식 컨테이너가 시작하는 동안 실패했습니다. '등등. – niaomingjian

6

이 주제는 다소 오래되었지만이 문제도 발생했습니다. Powermock이 같은 패키지에 같은 이름을 가진 2 개의 클래스가 있다는 것을 발견하면 (다른 의존성을 넘어서) java 버전 중 일부는 powermockito를 처리 할 수 ​​없다는 것을 알 수 있습니다.

Java 7_25보다 높은 버전에서는이 오류가 발생합니다.

+2

"Java 7_25보다 높은 버전에서는이 오류가 발생합니다.",이 정보는 유익합니다. –

+0

의미 : "powermockito를 처리 할 수 ​​없습니까?" 주석을 무시하는 것 외에도이를 처리 할 방법이 있습니까? – Line

+0

오래 전 이었지만 같은 종류의 패키지에 같은 이름의 클래스가 2 개가 없는지 확인하여 정렬했다고 생각합니다. 물론, 당신이 의존하는 2 개의 도서관이 있고 거기에 거주한다면 ... 그것은 어려울 것입니다. 그동안이 문제가 해결되었는지는 모르겠습니다. –

15

Crandrad의 대답은 비슷한 최종 솔루션에 도달하는 데 도움이되었습니다. 모든 SSL 관련 클래스를 제외해야만했습니다.

@PowerMockIgnore({"javax.management.*", "org.apache.http.conn.ssl.*", "com.amazonaws.http.conn.ssl.*", "javax.net.ssl.*"}) 
+4

경로를 더 추가해야하지만 내 목숨을 구해 줬습니다! @PowerMockIgnore ({ "javax.management. *", "org.apache.http.conn.ssl. *", "com.amazonaws. *", "javax.net.ssl. *", "com.sun. * "})' –

+0

com.sun에 대해 알아두면 유용합니다. –

+1

다음이 필요했습니다 : @PowerMockIgnore ({ "javax.management. *", "javax.crypto. *"}) –

관련 문제