IntelliJ 10.5'te testi çalıştırırken “NoSuchMethodError: org.hamcrest.Matcher.describeMismatch” alma


233

JUnit-dep 4.10 ve Hamcrest 1.3.RC2 kullanıyorum.

Aşağıdaki gibi görünen özel bir eşleştirici oluşturdum:

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 */
    }
}

Ant kullanarak komut satırından çalıştırıldığında mükemmel çalışıyor. Ancak IntelliJ'den çalıştırıldığında başarısız olur:

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)

Benim tahminim yanlış hamcrest kullanmasıdır.MatcherAssert. Hangi hamcrest.MatcherAssert'i kullandığını (yani hamcrest.MatcherAssert için hangi jar dosyasını kullandığını) nasıl bulabilirim? AFAICT, sınıf yolumdaki tek hamcrest kavanozları 1.3.RC2.

IntelliJ IDEA kendi JUnit veya Hamcrest kopyasını kullanıyor mu?

IntelliJ tarafından kullanılan CLASSPATH çalışma zamanının çıktısını nasıl alabilirim?

Yanıtlar:


272

Emin olun hamcrest kavanozun sizin daha ithalat sipariş üzerine yüksektir JUnit kavanozunuzdan .

JUnit kendi ile geliyororg.hamcrest.Matcher muhtemelen sınıfında kullanılan sınıfıyla .

Ayrıca junit-dep-4.10.jar dosyasını indirip kullanabilirsiniz. , hamcrest sınıfları olmadan JUnit olan .

mockito'da da hamcrest sınıfları var, bu yüzden de taşımanız gerekebilir


1
OP zaten '-dep-' kavanozunu kullandıklarını söyledi. Ama tahmin edin, JUnit kavanozundan Matcher sınıfını kullanıyor gibi görünüyor. Yani muhtemelen IDE kendi JUnit kopyasını kullanıyor.
MatrixFrog

2
IntelliJ'in junit.jar ve junit-4.8.jar kopyasını kaldırdım, junit-dep-4.10.jar dosyasını IntelliJ'in lib / dizinine yükledim ve sorun hala devam ediyor.
Noel Yap

8
JUnit 4.11, Hamcrest 1.3 ile uyumludur ve JUnit 4.10, Hamcrest 1.1 search.maven.org/remotecontent?filepath=junit/junit-dep/4.10/…
Muthu

23
mockito-all kullanmadığınızdan emin olun, ancak bunun yerine hamcrest hariç mockito-core kullandığınızdan emin olun
Ulf Lindback

1
Ofiste 7:33 PM bir ben bir tatil dışarı çıkmadan önce teslim gerekir önemli bir özellik üzerinde çalışıyorum ve Cuma, ben önümüzdeki hafta o tatil !!!!!! Nasıl da bu hatayı alabilirim !!!
Adelin

170

Bu sorun , zaten kullanımdan kaldırılmış olan sınıf yolunda mockito-all olduğunda da ortaya çıkar .

Mümkünse mokkito-çekirdeği ekleyin .

Junit, mockito ve hamcrest'i karıştırmak için maven yapılandırma:

<dependencies>
  <dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-core</artifactId>
    <version>1.3</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-library</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>
</dependencies>

2
Mockito'nun yeni sürümleri arasında powermock ile aynı hamcrest de var!
Tom Parkinson

3
Bu mockito-all yerine mockito-çekirdek olmalı mı?
user944849

3
Sadece tüm çekirdeklerin hızına ihtiyacınız varsa sadece çekirdeği dahil edebilirsiniz, ancak yukarıdakilerin tüm durumlarda çalışması gerekir. Bağımlılıkların sırası, mvn 3'ün öncelik sırasına göre en baştan başlamasıdır.
Tom Parkinson

3
Hamcrest 1.1'i içerdiğinden mockito-all'ı dahil etmemelisiniz, bunun yerine mockito-çekirdeği dahil edin ve hancrest'i hariç tutun (hepsinden yapamazsınız)
Ulf Lindback

1
"Mümkünse mokkito-çekirdeği ekleyin." Tamam, o zaman bu cevap neden hala mockito-all kullanıyor?
Gizli Rabbi

60

Sorun şu ki yanlıştı hamcrest.Matcher, değilhamcrest.MatcherAssert , sınıf kullanılıyordu. Bu bir junit-4.8 bağımlılığından çekiliyordu.

Test sırasında hangi kaynaktan hangi bağımlılıkların (ve sürümlerin) dahil edildiğini görmek için şunu çalıştırın:

mvn dependency:tree -Dscope=test

5
Aynı sorunu yaşadım. JUnit-dep ve Hamcrest-core kullanıyordum ama pom'da daha önce listelenen Powermock vardı, bu da JUnit'in JUnit-dep ve Hamcrest'ten önce dahil edilmesine neden oldu.
John B

9
Ayrıca mockito-all bazı Hamcrest sınıflarını içerir. Mockito-çekirdeği kullanmak ve hamcrest bağımlılığını dışlamak daha iyidir.
Brambo

3
Sadece aynı sorun üzerinde tökezledi. Çözüm, hamcrest 1.3
r3mbol

Tüm öneri de işe yaramadı bilinmeyenler için (değiştirmek çıkarmadan Bağımlılık amacıyla, exlusions, -allile -corevb ...): Ben sürüm 1.1 hamcrest geri değiştirmek zorunda kaldı ve şimdi her şey yeniden çalışır.
Felix Hagspiel

1
Benim ithalat değişti ne zaman benim için çalıştı import static org.mockito.Matchers.anyString;danimport static org.mockito.ArgumentMatchers.anyString;
Shrikant Prabhu

28

Aşağıdakiler bugün en doğru olanı olmalıdır. Not, junit 4.11 hamcrest çekirdeğine bağlıdır, bu yüzden mockito- all'in hamcrest 1.1'i içerdiğinden (bağlı değil) kullanılamayacağını belirtmeniz gerekmez.

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

3
JUnit 4.12'nin şimdi hamcrest-core 1.3'e bağlı olduğunu unutmayın.
JeeBee

Dışlanmak mockito-allbana yardım etti, değil mockito-core. Ayrıca Mockito'nun pom.xmlçalışmalarında Hamcrest'i ilan etti .
Kirill

13

Bu biraz uğraştıktan sonra benim için çalıştı

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

Benim için de aynı. Bağımlılıkları bu sıraya koymak, maven'in geçişli kusurları doğru bir şekilde çözmesine yardımcı olur. Hamcrest'i mockito-core veya mockito-all'tan tamamen hariç tutmak, pompanızdaki depsleri yeniden sıralaması durumunda daha güvenli olabilir.
Mat

4

Deneyin

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

onun yerine

expectMessage(message)

ExpectedExceptionKodu tamamlamak için özel veya yardımcı bir yöntem yazabilirsiniz .


4

Bu eski bir iş parçacığı olduğunu biliyorum ama ne benim için sorunu çözdü benim build.gradle dosyaları aşağıdaki ekliyordu. Yukarıda belirtildiği gibi bir uyumluluk sorunu varmockito-all

Muhtemelen faydalı yazı :

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'

1

Bu çok eski bir soru olmasına ve muhtemelen yukarıda bahsedilen fikirlerin çoğunun birçok sorunu çözmesine rağmen, yine de çözümü sorunumu düzelten toplulukla paylaşmak istiyorum.

Sorunun bir JSON-Array belirli bir öğe içerip içermediğini kontrol etmek için kullandım "hasItem" adlı bir işlev olduğunu buldum. Benim durumumda Long tipinde bir değer olup olmadığını kontrol ettim.

Ve bu da soruna yol açtı.

Her nasılsa, Eşleştiriciler Uzun tip değerlerle sorun yaşıyorlar. (JUnit veya Rest-Assured'ı bu kadar idk kullanmıyorum.

Bu yüzden, sorunu çözmek için yaptığım şey şuydu. Kullanmak yerine:

long ID = ...;

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

sadece Integer'a yayın yapman gerekiyor. Böylece çalışma kodu şöyle görünüyordu:

long ID = ...;

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

Bu muhtemelen en iyi çözüm değildir, ancak sadece yanlış / bilinmeyen veri türleri nedeniyle istisnanın da atılabileceğini belirtmek istedim.


0

Benim için çalışan hamcrest grubunu junit test derlemesinden hariç tutmaktı.

İşte benim build.gradle kodu:

testCompile ('junit:junit:4.11') {
    exclude group: 'org.hamcrest'
}

IntelliJ çalıştırıyorsanız gradle cleanIdea idea clean build, bağımlılıkları tekrar tespit etmek için çalıştırmanız gerekebilir .


0

Bunun en iyi cevap olmadığını biliyorum, ancak sınıf yolunu çalıştıramazsanız, bu bir B planı çözümü.

Test sınıfyolumda, descriptionMismatch yöntemi için varsayılan bir uygulama ile aşağıdaki arabirimi ekledim.

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_();
}

0

Bir gradle projesi var ve benim build.gradle bağımlılıkları bölümü şöyle görünür:

dependencies {
    implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.8.1'

    testImplementation group: 'org.mockito', name: 'mockito-all', version: '1.10.19'
    testImplementation 'junit:junit:4.12'
//    testCompile group: 'org.mockito', name: 'mockito-core', version: '2.23.4'

    compileOnly 'org.projectlombok:lombok:1.18.4'
    apt 'org.projectlombok:lombok:1.18.4'
}

bu istisnaya yol açar:

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)

Bu sorunu gidermek için, "mockito-all" yerine "mockito-core" ifadesini koydum.

dependencies {
    implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.8.1'

//    testImplementation group: 'org.mockito', name: 'mockito-all', version: '1.10.19'
    testImplementation 'junit:junit:4.12'
    testCompile group: 'org.mockito', name: 'mockito-core', version: '2.23.4'

    compileOnly 'org.projectlombok:lombok:1.18.4'
    apt 'org.projectlombok:lombok:1.18.4'
}

Mockito-all ve mockito-core arasındaki açıklama şu adreste bulunabilir: https://solidsoft.wordpress.com/2012/09/11/beyond-the-mockito-refcard-part-3-mockito-core-vs-mockito -tüm-in-mavengradle tabanlı-projeler /

Mockito'nun yanında mockito-all.jar da (1.9.5 itibariyle) iki bağımlılık içeriyor: Hamcrest ve Objenesis (bir an için yeniden paketlenmiş ASM ve CGLIB'yi atlayalım). Bunun nedeni, sadece bir sınıf yoluna koymak için bir JAR'ın içinde ihtiyaç duyulan her şeye sahip olmaktı. Garip görünebilir, ancak lütfen saf Ant'in (bağımlılık yönetimi olmadan) Java projeleri için en popüler inşa sistemi olduğu ve bir projenin gerektirdiği tüm harici JAR'ların (yani projemizin bağımlılıkları ve bağımlılıkları) başladığı zamanlarda Mockito gelişiminden başladığını unutmayın. manuel olarak indirilip bir yapı komut dosyasında belirtilmelidir.

Diğer yandan mockito-core.jar sadece Mockito sınıflarıdır (ayrıca paketlenmiş ASM ve CGLIB ile). Maven veya Gradle ile kullanıldığında, gerekli bağımlılıklar (Hamcrest ve Objenesis) bu araçlar tarafından yönetilir (otomatik olarak indirilir ve bir test sınıfı yoluna konur). Kullanılan sürümleri geçersiz kılmaya izin verir (örneğin, projelerimiz hiçbir zaman değil, geriye dönük uyumlu sürümü kullanıyorsa), ancak daha da önemlisi bu bağımlılıklar mockito-all.jar içinde gizlenmez, bu da bağımlılık analiz araçlarıyla olası sürüm uyumsuzluğunu tespit etmeyi sağlar. Bir projede bağımlılık yönetilen araç kullanıldığında bu çok daha iyi bir çözümdür.


0

Benim durumumda, eski bir hamcresti junit-vintage'dan hariç tutmak zorunda kaldım:

<dependency>
  <groupId>org.junit.vintage</groupId>
  <artifactId>junit-vintage-engine</artifactId>
  <scope>test</scope>
  <exclusions>
    <exclusion>
      <groupId>org.hamcrest</groupId>
      <artifactId>hamcrest-core</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.hamcrest</groupId>
  <artifactId>hamcrest</artifactId>
  <version>2.1</version>
  <scope>test</scope>
</dependency>

0

Bu benim için çalıştı. Hiçbir şeyi dışarıda bırakmaya gerek yok. Onun mockito-coreyerine az önce kullandımmockito-all

testCompile 'junit:junit:4.12'
testCompile group: 'org.mockito', name: 'mockito-core', version: '3.0.0'
testCompile group: 'org.hamcrest', name: 'hamcrest-library', version: '2.1'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.