239 votes

Obtention de "NoSuchMethodError : org.hamcrest.Matcher.describeMismatch" lors de l'exécution du test dans IntelliJ 10.5

J'utilise JUnit-dep 4.10 et Hamcrest 1.3.RC2.

J'ai créé un sélecteur personnalisé qui ressemble à ce qui suit :

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

Il fonctionne parfaitement bien lorsqu'il est exécuté à partir de la ligne de commande en utilisant Ant. Mais lorsqu'il est exécuté depuis IntelliJ, il échoue avec :

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)

Je pense qu'il utilise le mauvais hamcrest.MatcherAssert. Comment puis-je trouver quel hamcrest.MatcherAssert il utilise (c'est-à-dire quel fichier jar il utilise pour hamcrest.MatcherAssert) ? AFAICT, le seul jar hamcrest dans mon classpath est 1.3.RC2.

IntelliJ IDEA utilise-t-il sa propre copie de JUnit ou de Hamcrest ?

Comment puis-je afficher le CLASSPATH du runtime qu'IntelliJ utilise ?

1voto

Cela a fonctionné pour moi. Pas besoin d'exclure quoi que ce soit. J'ai juste utilisé mockito-core au lieu de mockito-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'

0voto

Jason D Points 475

Ce qui a fonctionné pour moi, c'est d'exclure le groupe hamcrest de la compilation du test junit.

Voici le code de mon build.gradle :

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

Si vous utilisez IntelliJ, vous devrez peut-être exécuter gradle cleanIdea idea clean build pour détecter à nouveau les dépendances.

0voto

Francis Points 1880

Je sais que ce n'est pas la meilleure réponse, mais si vous ne parvenez pas à faire fonctionner le classpath, c'est une solution de secours.

Dans mon classpath de test, j'ai ajouté l'interface suivante avec une implémentation par défaut pour la méthode 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<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_();
}

0voto

Pavel Points 70

J'ai un projet gradle et quand ma section dépendances de build.gradle ressemble à ceci :

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

cela conduit à cette exception :

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)

Pour résoudre ce problème, j'ai remplacé "mockito-all" par "mockito-core".

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

L'explication entre mockito-all y mockito-core peuvent être trouvés ici : https://solidsoft.wordpress.com/2012/09/11/beyond-the-mockito-refcard-part-3-mockito-core-vs-mockito-all-in-mavengradle-based-projects/

mockito-all.jar en plus de Mockito lui-même contient également (à partir de 1.9.5) deux dépendances : Hamcrest et Objenesis (omettons pour l'instant ASM et CGLIB repackagés). CGLIB pour un moment). La raison était d'avoir tout ce qui est nécessaire à l'intérieur d'un seul JAR pour le mettre simplement dans le classpath. Cela peut sembler étrange, mais rappelez-vous que le développement de Mockito a commencé à une époque où Ant pur (sans gestion des dépendances) était le système de construction le plus populaire. pour les projets Java et tous les JARs externes requis par un projet (i.e. notre projet). projet (c'est-à-dire les dépendances de notre projet et leurs dépendances) devaient être téléchargés manuellement et spécifiés dans un build script.

D'autre part, mockito-core.jar n'est que des classes de Mockito (avec également ASM et CGLIB repackagés). Lorsque vous l'utilisez avec Maven ou Gradle, les dépendances dépendances requises (Hamcrest et Objenesis) sont gérées par ces outils (téléchargées automatiquement et placées dans un test). (téléchargées automatiquement et placées sur un classpath de test). Il permet de de remplacer les versions utilisées (par exemple si nos projets n'utilisent jamais, mais mais rétrocompatible), mais ce qui est le plus important c'est que ces dépendances ne sont pas cachées à l'intérieur de mockito-all.jar ce qui permet de détecter une éventuelle incompatibilité de version avec des outils d'analyse des dépendances. de dépendance. C'est une bien meilleure solution lorsque l'outil de gestion des dépendances est utilisé dans un projet.

0voto

Udara Seneviratne Points 677

Pour jUnit 4.12, la combinaison de dépendances suivante a résolu mon problème.

<dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.12</version>
   <scope>test</scope>
</dependency>
<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>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X