Mockito + PowerMock LinkageError सिस्टम क्लास का मजाक उड़ाते हुए


166

मुझे ऐसा कोड स्निपेट मिला है:

@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)

क्या आप जानते हैं कि मैं इसे कैसे रोक सकता हूं? मैं शायद इस तरह के कोड का मजाक उड़ाने का एक और तरीका है:

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

यह क्या है कि आप नकली करने की कोशिश कर रहे हैं? और क्यों?
नेल्सएच

पहला परीक्षण गेटर्स और सेटर्स टेस्ट है, मैं वहां कंस्ट्रक्टर को बुला रहा हूं (और वहां अपवाद होता है)। दूसरा है कंस्ट्रक्टर टेस्ट। मैं यह जानना चाहता हूं कि तीसरे कोड स्निपेट में किन संसाधनों की गणना है।
वोज्शिएक रेसलेवस्की

1
सबसे पहले, यह मुझे दिखता है कि आपके परीक्षण आपके कार्यान्वयन के लिए बहुत कसकर युग्मित हैं। अनुभव से, यह नाजुक परीक्षणों को जन्म देगा। अधिमानतः, आप अपने परीक्षण लिखते समय "ब्लैक बॉक्स" सोचना चाहते हैं। "कोड का यह टुकड़ा क्या करना है", बजाय "यह कोड का टुकड़ा यह कैसे कर रहा है"। दूसरा, मुझे लगता है कि आप सिर्फ संसाधनों का एक सेट बनाने से बेहतर होंगे और जावा रनटाइम को क्लास लोडिंग से निपटने दें।
नेल्सएच

संसाधनों के विभिन्न सेट बनाना संभव है, क्योंकि वे जहां मामलों की जांच करते हैं?
वोज्शिएक रेसलेवस्की

ज़रूर। आपके लिए सबसे आसान शायद संसाधनों के नाम का परिमार्जन है। फिर आप अपने परीक्षणों में विभिन्न संसाधन नाम पारित कर सकते हैं।
नेल्सएच

जवाबों:


408

इस टिप्पणी को अपने परीक्षण वर्ग में जोड़ने का प्रयास करें:

@PowerMockIgnore("javax.management.*")

मेरे लिए काम किया।


2
परिशुद्धता * "अपने टेस्ट क्लास के लिए"। सरल और उपयोगी उत्तर!
pdem

3
क्या यह कोड या विन्यास द्वारा भी किया जा सकता है? मुझे ऐसा करने का कोई तरीका नहीं मिला। हमारे पास सैकड़ों परीक्षण हैं ... मैं उन सभी को समायोजित नहीं कर सकता।
फ्रेडरिक लीटनबर्गर

1
@FredericLeitenberger नीचे मेरा जवाब देखें
user3474985

2
क्या आप कृपया इस फिक्स के इंटेंस और अर्थ को भी समझा सकते हैं? हम उस लाइन का उपयोग करके PowerMockito को क्या निर्देश दे रहे हैं?
स्वप्निल बी।

33

यहाँ स्वीकृत प्रतिक्रिया के समान, मैंने SSL संबंधित सभी वर्गों को बाहर करने के लिए समाप्त कर दिया है:

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

मेरी कक्षा के शीर्ष पर इसे जोड़ने से त्रुटि हल हो गई।


5
फिर भी कुछ और रास्ते जोड़ने की जरूरत थी लेकिन आपने मेरी जान बचा ली! @PowerMockIgnore({"javax.management.*", "org.apache.http.conn.ssl.*", "com.amazonaws.*", "javax.net.ssl.*","com.sun.*"})
फ्रांसिस्को लोपेज-सांचो

Com.sun के बारे में भी जानकर अच्छा लगा।
जेसन डी

1
मुझे निम्नलिखित की आवश्यकता थी: @PowerMockIgnore ({"javax.management। *", "Javax.crypto। *"})
क्रिस्टोफ Neirynck

2
इसने मुझे बचाया: @PowerMockIgnore ({"javax.management। *", "Org.apache.http। *", "Com.amazonaws.http.conn.ssl।" "," Javax.net.ssl। * ""। , "com.sun। *", "javax.xml। ​​*", "javax.crypto। *"})
फ़याज़ अहमद

26

क्लास लोडर संघर्ष, इसका उपयोग करें:@PowerMockIgnore("javax.management.*")

चलो नकली classloader लोड नहीं javax.*. यह काम करता है।


उपयोग करने के बाद @PowerMockIgnore("javax.management.*"), परीक्षण वर्ग अच्छी तरह से काम करता है। लेकिन के रूप में चल Junit testउस पर पैकेज मिला Failed to load ApplicationContextत्रुटि। org.apache.catalina.LifecycleException: A child container failed during startऔर इसी तरह।
niaomingjian

8

यह एक पुराना विषय हो सकता है, लेकिन मैं भी इस समस्या में भाग गया हूं। पता चलता है कि जावा संस्करणों में से कुछ powermockito को संभाल नहीं सकते हैं जब powermock को पता चलता है कि एक ही पैकेज (अलग-अलग निर्भरता) में एक ही नाम के साथ 2 कक्षाएं हैं।

जावा 7_25 से अधिक किसी भी संस्करण के साथ यह त्रुटि देता है।


2
"जावा 7_25 से अधिक किसी भी संस्करण के साथ यह त्रुटि देता है।", यह जानकारीपूर्ण है।
काजल सिन्हा

इसका क्या अर्थ है: "powermockito को संभाल नहीं सकता"? क्या एनोटेशन द्वारा अनदेखी करने के अलावा इससे निपटने का कोई तरीका है?
लाइन

यह बहुत समय पहले की बात है, लेकिन मुझे लगता है कि हमने यह सुनिश्चित कर लिया कि एक ही तरह के पैकेज में एक ही नाम के साथ 2 कक्षाएं नहीं हैं। बेशक, अगर आपके पास 2 पुस्तकालय हैं, जो आप पर निर्भर करते हैं, और वे वहां रहते हैं ... यह मुश्किल होने वाला है। मुझे नहीं पता कि इस बीच यह मुद्दा तय किया गया है या नहीं।
रेंस ग्रोएनवेल्ड

3

सिस्टम कक्षाओं का मजाक बनाने के लिए, उस कक्षा को तैयार करें जो परीक्षा का लक्ष्य है, न कि Thread.class। ऐसा कोई तरीका नहीं है कि पावरमॉक साधन कर सकेगा Thread.classक्योंकि जेवीएम स्टार्टअप के दौरान इसकी आवश्यकता होती है - इससे पहले कि पावरमॉक उपकरण कर सके।

जिस तरह से इंस्ट्रूमेंटेशन काम करता है, एक बार एक क्लास लोड होने के बाद, यह अब इंटस्टेड नहीं हो सकता है।

PowerMock विकी देखें ।


3

PowerMock 1.7.0 में उपयोगकर्ता-परिभाषित वैश्विक कॉन्फ़िगरेशन को आपकी परियोजना के क्लासपाथ में जोड़ा जा सकता है। PowerMockConfig

org/powermock/extensions/configuration.properties

बस गुण फ़ाइल में एक पंक्ति जोड़ें जैसे:

powermock.global-ignore=javax.management.*

यह आपकी परियोजना के सभी परीक्षण वर्गों के लिए त्रुटि को हल करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.