java - IntelliJ 10.5 में परीक्षण चलाते समय "NoSuchMethodError:org.hamcrest.Matcher.describeMismatch" प्राप्त करना




junit intellij-idea junit4 (9)

थोड़ा सा संघर्ष करने के बाद यह मेरे लिए काम किया

<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-all</artifactId>
    <version>1.3</version>
    <scope>test</scope>
 </dependency>

 <dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-all</artifactId>
    <version>1.9.5</version>
    <scope>test</scope>
 </dependency>

 <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
 </dependency>

मैं जुनीट-डीपी 4.10 और हैमक्रिस्ट 1.3.आरसी 2 का उपयोग कर रहा हूं।

मैंने एक कस्टम मैचर बनाया है जो निम्न जैसा दिखता है:

public static class MyMatcher extends TypeSafeMatcher<String> {
    @Override
    protected boolean matchesSafely(String s) {
        /* implementation */
    }

    @Override
    public void describeTo(Description description) {
        /* implementation */
    }

    @Override
    protected void describeMismatchSafely(String item, Description mismatchDescription) {

        /* implementation */
    }
}

चींटी का उपयोग करते हुए कमांड लाइन से चलाते समय यह पूरी तरह से ठीक काम करता है। लेकिन जब इंटेलिजे से भागते हैं, तो यह विफल रहता है:

java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:18)
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
    at com.netflix.build.MyTest.testmyStuff(MyTest.java:40)

मेरा अनुमान है कि यह गलत hamcrest का उपयोग कर रहा है। MatcherAssert। मुझे यह कैसे पता चलेगा कि कौन सा hamcrest.MatcherAssert इसका उपयोग कर रहा है (यानी कौन सा जार फ़ाइल यह हैमक्रिस्ट के लिए उपयोग कर रही है। मैचरएस्र्ट)? AFAICT, मेरे क्लासपाथ में एकमात्र हैमक्रिस्ट जार 1.3.आरसी 2 है।

IntelliJ IDEA JUnit या Hamcrest की अपनी प्रति का उपयोग कर रहा है?

मैं रनटाइम क्लासस्पैट को आउटपुट कैसे कर सकता हूं कि इंटेलिजे का उपयोग कर रहा है?


निम्नलिखित आज सबसे सही होना चाहिए। नोट, जूनिट 4.11 हैमक्रिस्ट-कोर पर निर्भर करता है, इसलिए आपको इसे निर्दिष्ट करने की आवश्यकता नहीं है, मॉकिटो-सभी का उपयोग नहीं किया जा सकता है क्योंकि इसमें शामिल है (पर निर्भर नहीं है) hamcrest 1.1

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>1.10.8</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>

इस तथ्य के बावजूद कि यह एक बहुत पुराना सवाल है और संभवतः कई पूर्ववर्ती विचारों में कई समस्याएं हल हुई हैं, मैं अभी भी उस समस्या के साथ समाधान साझा करना चाहता हूं जिसने मेरी समस्या तय की है।

मैंने पाया कि समस्या "हैटिम" नामक एक फ़ंक्शन था जिसे मैं जांचने के लिए उपयोग कर रहा था कि JSON-Array में कोई विशिष्ट आइटम है या नहीं। मेरे मामले में मैंने लंबे प्रकार के मूल्य की जांच की।

और इससे समस्या उत्पन्न हुई।

किसी भी तरह, मैचर्स को लंबे प्रकार के मूल्यों के साथ समस्याएं होती हैं। (मैं जुनीट या बाकी आश्वासन का इतना उपयोग नहीं करता हूं। बिल्कुल क्यों, लेकिन मुझे लगता है कि लौटा JSON-डेटा में केवल इंटीजर होते हैं।)

तो मैंने वास्तव में समस्या को ठीक करने के लिए क्या किया था निम्नलिखित था। के बजाय का उपयोग करने का:

long ID = ...;

...
.then().assertThat()
  .body("myArray", hasItem(ID));

आपको बस इंटीजर पर डालना होगा। तो कामकाजी कोड इस तरह दिखता था:

long ID = ...;

...
.then().assertThat()
  .body("myArray", hasItem((int) ID));

शायद यह सबसे अच्छा समाधान नहीं है, लेकिन मैं बस उल्लेख करना चाहता था कि गलत / अज्ञात डेटा प्रकारों के कारण अपवाद भी फेंक दिया जा सकता है।


प्रयत्न

expect(new ThrowableMessageMatcher(new StringContains(message)))

के बजाय

expectMessage(message)

आप कोड को लपेटने के लिए एक कस्टम ExpectedException या उपयोगिता विधि लिख सकते हैं।


मुझे पता है कि यह सबसे अच्छा जवाब नहीं है, लेकिन यदि आप क्लासपाथ काम नहीं कर पा रहे हैं, तो यह एक योजना बी समाधान है।

मेरे टेस्ट क्लासपाथ में, मैंने वर्णन मिस्चैच विधि के लिए डिफ़ॉल्ट कार्यान्वयन के साथ निम्न इंटरफ़ेस जोड़ा।

package org.hamcrest;

/**
 * PATCH because there's something wrong with the classpath. Hamcrest should be higher than Mockito so that the BaseMatcher
 * implements the describeMismatch method, but it doesn't work for me. 
 */
public interface Matcher<T> extends SelfDescribing {

    boolean matches(Object item);

    default void describeMismatch(Object item, Description mismatchDescription) {
        mismatchDescription.appendDescriptionOf(this).appendValue(item);
    }

    @Deprecated
    void _dont_implement_Matcher___instead_extend_BaseMatcher_();
}

मुझे पता है कि यह एक पुराना धागा है, लेकिन मेरे लिए इस मुद्दे को हल करने के लिए मेरे निर्माण .gradle फ़ाइलों में निम्नलिखित जोड़ रहा था। जैसा कि पहले से ही बताया गया है, mockito-all साथ एक संगतता मुद्दा है

संभवतः उपयोगी post :

testCompile ('junit:junit:4.12') {
    exclude group: 'org.hamcrest'
}
testCompile ('org.mockito:mockito-core:1.10.19') {
    exclude group: 'org.hamcrest'
}
testCompile 'org.hamcrest:hamcrest-core:1.3'

सुनिश्चित करें कि आपके जुनीट जार की तुलना में आयात आदेश पर हैमक्रिस्ट जार अधिक है।

org.hamcrest.Matcher अपने स्वयं के org.hamcrest.Matcher क्लास के साथ आता है जिसका शायद उपयोग किया जा रहा है।

आप जूनिट-डीपी -4.10.jar को भी डाउनलोड और उपयोग कर सकते हैं, जो कि बिना घुमावदार वर्गों के जुनीट है।

मॉकिटो में भी इसमें अवरोधक वर्ग हैं, इसलिए आपको इसे फिर से चलाने की आवश्यकता हो सकती है


समस्या यह थी कि गलत hamcrest.Matcher , hamcrest.MatcherAssert नहीं। hamcrest.MatcherAssert , कक्षा का उपयोग किया जा रहा था। एक जूनिट -4.8 निर्भरता से खींचा जा रहा था मेरी निर्भरताओं में से एक निर्दिष्ट था।

यह देखने के लिए कि परीक्षण के दौरान किस स्रोत से निर्भरता (और संस्करण) शामिल हैं, चलाएं:

mvn dependency:tree -Dscope=test

यदि जावा भाषा विशिष्टता से हम एक से अधिक विधि लागू हो सकते हैं, तो हम सबसे विशिष्ट विधि का चयन करते हैं , अनुच्छेद 15.12.2.5 :

m नामक एक परिवर्तनीय धैर्य सदस्य विधि एक ही नाम के किसी अन्य परिवर्तनीय धैर्य सदस्य विधि से अधिक विशिष्ट है यदि (या <: means subtyping ):

  1. एक सदस्य विधि में एन पैरामीटर होते हैं और दूसरे के पास के पैरामीटर होते हैं, जहां n ≥ k, और:
    • पहली सदस्य विधि के पैरामीटर के प्रकार टी 1, ..., टीएन -1, टीएन [] हैं। ( हमारे पास केवल एक T_n है [], जो इंटीजर है [], n = 1 )
    • अन्य विधि के पैरामीटर के प्रकार यू 1, ..., यूके -1, यूके [] हैं। ( फिर केवल एक पैरामीटर, जो int [], k = 1 है )
    • यदि दूसरी विधि जेनेरिक है तो आर 1 दें ... आरपी (पी ≥ 1) इसके प्रकार के पैरामीटर हो, बीएल को आरएल (1 ≤ एल ≤ पी) की घोषित सीमा हो, चलो ए 1 ... एपी अनुमानित प्रकार के तर्क हो (§15.12.2.7) प्रारंभिक बाधाओं के तहत इस आमंत्रण के लिए टीआई << उई (1 ≤ i ≤ के -1) और टीआई << ब्रिटेन (के ≤ i ​​≤ एन), और सी = उई [आर 1 = ए 1, चलो। .., आरपी = एपी] (1 ≤ i ≤ के)। ( विधि सामान्य नहीं है )
    • अन्यथा, सी = उई (1 ≤ i ≤ के) दें। ( एस 1 = int [] )
    • सभी जे से 1 से के -1 तक, टीजे <: एसजे, और, ( यहां कुछ भी नहीं )
    • सभी जे से के लिए एन, टीजे <: स्क, और, ( टी 1 <: एस 1, इंटीजर [] <: int [] ) की तुलना करें
    • यदि दूसरी विधि उपरोक्त वर्णित एक सामान्य विधि है, तो अल <: Bl [R1 = A1, ..., आरपी = एपी] (1 ≤ एल ≤ पी)। ( विधि सामान्य नहीं है )

यद्यपि आदिम int इंटीजर रैपर करने के लिए autoboxed है, int[] Integer[] लिए autoboxed नहीं है, पहली स्थिति की तुलना में नहीं है।

दूसरी स्थिति लगभग एक ही है।

ऐसी अन्य स्थितियां भी हैं जो पकड़ नहीं लेती हैं, और फिर जेएलएस के कारण:

हम कहते हैं कि विधि आमंत्रण संदिग्ध है, और एक संकलन-समय त्रुटि होती है।







java junit intellij-idea junit4 hamcrest