Ottenere “NoSuchMethodError: org.hamcrest.Matcher.describeMismatch” quando si esegue il test in IntelliJ 10.5

Sto usando JUnit-dep 4.10 e Hamcrest 1.3.RC2.

Ho creato un matcher personalizzato simile al seguente:

public static class MyMatcher extends TypeSafeMatcher { @Override protected boolean matchesSafely(String s) { /* implementation */ } @Override public void describeTo(Description description) { /* implementation */ } @Override protected void describeMismatchSafely(String item, Description mismatchDescription) { /* implementation */ } } 

Funziona perfettamente bene quando viene eseguito dalla riga di comando usando Ant. Ma quando viene eseguito da IntelliJ, non riesce con:

 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) 

La mia ipotesi è che stia usando hamcrest.MatcherAssert sbagliato. Come faccio a sapere quale hamcrest.MatcherAssert sta usando (cioè quale file jar sta usando per hamcrest.MatcherAssert)? AFAICT, gli unici jar di hamcrest nel mio classpath sono 1.3.RC2.

IntelliJ IDEA utilizza la propria copia di JUnit o Hamcrest?

Come posso generare il CLASSPATH di runtime utilizzato da IntelliJ?

Assicurati che il jar hamcrest sia più in alto nell’ordine di importazione del tuo barattolo JUnit .

JUnit viene fornito con la propria class org.hamcrest.Matcher che viene probabilmente utilizzata al suo posto.

È anche ansible scaricare e utilizzare junit-dep-4.10.jar che invece è JUnit senza le classi hamcrest.

anche il mockito contiene le classi hamcrest, quindi potrebbe essere necessario spostarlo \ riordinarlo

Questo problema si verifica anche quando hai mockito-all sul tuo percorso di class, che è già deprecato.

Se ansible, includi solo mockito-core .

Maven config per la miscelazione di junit, mockito e hamcrest:

   org.hamcrest hamcrest-core 1.3 test   org.hamcrest hamcrest-library 1.3 test   org.mockito mockito-all 1.9.5 test   junit junit 4.11 test   

Il problema era che veniva hamcrest.Matcher la hamcrest.Matcher sbagliata, non hamcrest.MatcherAssert . Era stato tirato fuori da una dipendenza da junit-4.8 che una delle mie dipendenze stava specificando.

Per vedere quali dipendenze (e versioni) sono incluse da quale fonte durante il test, eseguire:

 mvn dependency:tree -Dscope=test 

Il seguente dovrebbe essere il più corretto oggi. Nota, junit 4.11 dipende da hamcrest-core, quindi non è necessario specificarlo, mockito-all non può essere utilizzato poiché include (non dipende da) hamcrest 1.1

  junit junit 4.11 test   org.mockito mockito-core 1.10.8 test   org.hamcrest hamcrest-core    

Questo ha funzionato per me dopo aver faticato un po ‘

  org.hamcrest hamcrest-all 1.3 test   org.mockito mockito-all 1.9.5 test   junit junit 4.11 test  

Provare

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

invece di

expectMessage(message)

È ansible scrivere un ExpectedException personalizzato o un metodo di utilità per racchiudere il codice.

So che questo è un thread vecchio, ma quello che ha risolto il problema per me è stato aggiungere quanto segue ai miei file build.gradle. Come già detto sopra c’è un problema di compatibilità con mockito-all

Post forse utile:

 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' 

Nonostante il fatto che questa sia una domanda molto vecchia e probabilmente molte delle idee precedenti hanno risolto molti problemi, voglio comunque condividere la soluzione con la comunità che ha risolto il mio problema.

Ho scoperto che il problema era una funzione chiamata “hasItem” che stavo usando per verificare se un array JSON contiene o meno un object specifico. Nel mio caso ho controllato per un valore di tipo Long.

E questo ha portato al problema.

In qualche modo, i Matcher hanno problemi con i valori di tipo Long. (Non uso JUnit o Rest-Assured così tanto idk, esattamente perché, ma suppongo che i dati JSON restituiti contengano solo numeri interi).

Quindi quello che ho fatto per risolvere il problema è stato il seguente. Invece di usare:

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

devi solo trasmettere a Integer. Quindi il codice funzionante assomigliava a questo:

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

Probabilmente non è la soluzione migliore, ma volevo solo menzionare che l’eccezione può anche essere generata a causa di tipi di dati errati / sconosciuti.

Ciò che ha funzionato per me è stato escludere il gruppo hamcrest dalla compilazione del test di junit.

Ecco il codice dal mio build.gradle:

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

Se stai utilizzando IntelliJ potresti dover eseguire gradle cleanIdea idea clean build per rilevare nuovamente le dipendenze.

So che non è la risposta migliore, ma se non riesci a far funzionare il classpath, questa è una soluzione di piano B.

Nel mio classpath di test, ho aggiunto la seguente interfaccia con un’implementazione predefinita per il metodo describeMismatch.

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