Получение NoSuchMethodError: org.hamcrest.Matcher.describeMismatch при запуске теста в IntelliJ 10.5

Я использую JUnit-dep 4.10 и Hamcrest 1.3.RC2.

Я создал настраиваемый сопоставитель, который выглядит следующим образом:

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. Но при запуске из IntelliJ он не работает:

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 он использует (то есть какой файл jar он использует для hamcrest.MatcherAssert)? AFAICT, единственные баночки hamcrest в моем пути к классам - 1.3.RC2.

Использует ли IntelliJ IDEA собственную копию JUnit или Hamcrest?

Как вывести CLASSPATH среды выполнения, которую использует IntelliJ?


person Noel Yap    schedule 23.10.2011    source источник


Ответы (15)


Убедитесь, что банка hamcrest выше в порядке импорта, чем банка JUnit.

JUnit имеет собственный класс org.hamcrest.Matcher, который, вероятно, используется вместо него.

Вы также можете загрузить и использовать вместо него junit-dep-4.10.jar, который представляет собой JUnit без классов hamcrest.

mockito также имеет классы hamcrest в нем, поэтому вам может потребоваться переместить \ изменить его порядок

person Garrett Hall    schedule 24.10.2011
comment
OP сказал, что они уже использовали банку «-dep-». Но ваше предположение, что он использует класс Matcher из JUnit jar, звучит правильно. Так что, вероятно, IDE использует собственную копию JUnit. - person MatrixFrog; 25.10.2011
comment
Я удалил IntelliJ-копию junit.jar и junit-4.8.jar, установил junit-dep-4.10.jar в каталог lib / IntelliJ, и проблема все еще возникает. - person Noel Yap; 25.10.2011
comment
Вы проверили .classppath, чтобы убедиться, что нет других записей JUnit? - person Garrett Hall; 25.10.2011
comment
Я только что проверил путь к классам среды выполнения, указанный в первой строке, при отладке теста. Единственный jar-файл с MatcherAssert - это hamcrest-core-1.3. - person Noel Yap; 25.10.2011
comment
отличный мужик! Я столкнулся с этой проблемой в среде OSGI ... когда у меня был Junit 4 в моих зависимостях ... Я не видел плагин hamcrest, когда искал его. Однако, если я удалил Junit и стал искать ... Я нашел его в списке. - person Vikram; 12.04.2013
comment
JUnit 4.11 совместим с Hamcrest 1.3, а JUnit 4.10 совместим с Hamcrest 1.1 search.maven.org/remotecontent?filepath=junit/junit-dep/4.10/ - person Muthu; 15.05.2014
comment
убедитесь, что вы НЕ используете mockito-all, а вместо этого используете mockito-core с исключением hamcrest - person Ulf Lindback; 21.11.2014
comment
В офисе 7:33 вечера, и я работаю над важной функцией, которую я должен предоставить перед выходом в отпуск, и сейчас пятница, я в этом отпуске на следующей неделе !!!!!! Как, черт возьми, я мог получить эту ошибку сейчас !!! - person Adelin; 15.07.2016
comment
выше по импорту что вы имеете в виду? - person Adelin; 15.07.2016
comment
Это относится и к Eclipse. - person ojchase; 28.02.2019
comment
У меня такое же столкновение сJUnit 4.11 и Hamcrest 2.0.0.0. - person flaz14; 06.03.2019

Эта проблема также возникает, когда у вас есть mockito-all на пути к классу, который уже устарел.

Если возможно, просто включите mockito-core.

Конфигурация Maven для смешивания junit, mockito и hamcrest:

<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>
person Tom Parkinson    schedule 24.05.2013
comment
Это как раз та подсказка, которая мне была нужна. Идея просто состоит в том, чтобы проверить все эти über jar-файлы на наличие скрытых зависимостей. Или лучше не лениться и вообще ими не пользоваться. - person Oliver; 17.12.2013
comment
Точно так же, как новые версии mockito включают hamcrest, так же как и powermock! - person Tom Parkinson; 17.12.2013
comment
Должно ли это быть mockito-core вместо mockito-all? - person user944849; 14.01.2014
comment
Вы можете включить только ядро, если оно вам нужно только в темпе, однако вышеперечисленное должно работать во всех случаях. Порядок зависимостей - это важный бит mvn 3, который начинается сверху в порядке приоритета. - person Tom Parkinson; 14.01.2014
comment
Вы НЕ должны включать mockito-all, поскольку он включает hamcrest 1.1, вместо этого включите mockito-core и исключите из него hancrest (что вы не можете сделать для всех) - person Ulf Lindback; 21.11.2014
comment
Сэкономил мне несколько часов. Спасибо! - person Bruno P. Kinoshita; 10.04.2016
comment
Если возможно, просто включите mockito-core ... Хорошо, тогда почему в этом ответе все еще используется mockito-all? - person Stealth Rabbi; 17.01.2020

Проблема заключалась в том, что использовался неправильный класс hamcrest.Matcher, а не hamcrest.MatcherAssert. Это было извлечено из зависимости junit-4.8, которую указывала одна из моих зависимостей.

Чтобы узнать, какие зависимости (и версии) из какого источника включены во время тестирования, запустите:

mvn dependency:tree -Dscope=test
person Noel Yap    schedule 24.10.2011
comment
Я была такая же проблема. Я использовал JUnit-dep и Hamcrest-core, но у меня был Powermock, указанный ранее в pom, в результате чего JUnit был включен до JUnit-dep и Hamcrest. - person John B; 03.11.2011
comment
Также mockito-all включает в себя некоторые классы Hamcrest. Лучше использовать mockito-core и исключить зависимость hamcrest. - person Brambo; 24.04.2012
comment
Просто наткнулся на ту же проблему. Решением было повышение версии junit до 4.11, которая совместима (т.е. содержит классы из) с hamcrest 1.3. - person r3mbol; 12.09.2013
comment
Для тех, у кого все предложения не сработали (порядок зависимостей, исключения, удаление, замена -all на -core и т. Д.): Мне пришлось вернуть hamcrest к версии 1.1, и теперь все снова работает. - person Felix Hagspiel; 11.01.2019
comment
для меня это сработало, когда я изменил свой импорт на import static org.mockito.Matchers.anyString; с import static org.mockito.ArgumentMatchers.anyString; - person Shrikant Prabhu; 17.01.2019

Следующее сегодня должно быть наиболее правильным. Обратите внимание, что junit 4.11 зависит от hamcrest-core, поэтому вам не нужно указывать, что mockito-all вообще не может использоваться, поскольку он включает (не зависит от) 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>
person Ulf Lindback    schedule 21.11.2014
comment
Обратите внимание, что JUnit 4.12 теперь зависит от hamcrest-core 1.3. - person JeeBee; 06.03.2015
comment
Мне помогло исключение из mockito-all, а не mockito-core. Также работает объявление Hamcrest перед Mockito в pom.xml. - person Kirill; 19.01.2018

Это сработало для меня после небольшой борьбы

<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>
person Raul    schedule 12.04.2014
comment
Мне то же. Размещение зависимостей в этом порядке помогает maven правильно разрешать переходные зависимости. Явное исключение Hamcrest из mockito-core или mockito-all может быть более безопасным, если кто-то изменит порядок в вашем помпе. - person Mat; 26.01.2017

Я знаю, что это старый поток, но для меня проблема была решена путем добавления следующего в мои файлы build.gradle. Как уже было сказано выше, существует проблема совместимости с mockito-all

Возможно полезное сообщение:

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'
person Kai    schedule 22.05.2017

Пытаться

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

вместо того

expectMessage(message)

Вы можете написать собственный ExpectedException или служебный метод, чтобы завершить код.

person Qiang Li    schedule 05.02.2015

По состоянию на июль 2020 года у меня работали следующие зависимости в pom.xml:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13</version>
</dependency>
<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest</artifactId>
    <version>2.1</version>
</dependency>

С этой библиотекой junit 4.13 и hamcrest он использует hamcrest.MatcherAssert при утверждении и выдает исключение - введите описание изображения здесь

person zeinkap    schedule 06.07.2020

Несмотря на то, что это очень старый вопрос и, вероятно, многие из вышеупомянутых идей решили многие проблемы, я все же хочу поделиться решением с сообществом, которое устранило мою проблему.

Я обнаружил, что проблема заключалась в функции под названием «hasItem», которую я использовал, чтобы проверить, содержит ли JSON-массив конкретный элемент. В моем случае я проверил значение типа Long.

И это привело к проблеме.

Почему-то у Matchers возникают проблемы со значениями типа Long. (Я не использую JUnit или Rest-Assured так часто, поэтому я знаю почему, но я предполагаю, что возвращенные данные JSON содержат только целые числа.)

Итак, что я сделал, чтобы решить проблему, было следующее. Вместо использования:

long ID = ...;

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

вам просто нужно преобразовать в Integer. Итак, рабочий код выглядел так:

long ID = ...;

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

Вероятно, это не лучшее решение, но я просто хотел упомянуть, что исключение также может быть вызвано из-за неправильных / неизвестных типов данных.

person Siro    schedule 27.11.2017

В моем случае мне пришлось исключить более старый хамкрест из junit-vintage:

<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>
person André    schedule 09.02.2019

Что сработало для меня, так это исключение группы hamcrest из тестовой компиляции junit.

Вот код из моего build.gradle:

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

Если вы используете IntelliJ, вам может потребоваться запустить gradle cleanIdea idea clean build, чтобы снова обнаружить зависимости.

person Jason D    schedule 10.05.2016

Я знаю, что это не лучший ответ, но если вы не можете заставить работать путь к классам, это решение плана Б.

В моем тестовом пути к классам я добавил следующий интерфейс с реализацией по умолчанию для метода 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_();
}
person Francis    schedule 30.05.2016

У меня есть проект gradle, и когда мой раздел зависимостей build.gradle выглядит так:

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

это приводит к этому исключению:

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)

чтобы решить эту проблему, я заменил "mockito-all" на "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'
}

Объяснение между mockito-all и mockito-core можно найти здесь: https://solidsoft.wordpress.com/2012/09/11/запределами-the-mockito-refcard-part-3-mockito-core-vs-mockito-all-in-mavengradle-based-projects/

mockito-all.jar помимо самого Mockito также содержит (начиная с 1.9.5) две зависимости: Hamcrest и Objenesis (давайте на время опустим переупакованные ASM и CGLIB). Причина заключалась в том, чтобы иметь все необходимое в одном JAR, чтобы просто поместить его в путь к классам. Это может выглядеть странно, но, пожалуйста, помните, что разработка Mockito началась во времена, когда чистый Ant (без управления зависимостями) был самой популярной системой сборки для проектов Java, а все внешние JAR, необходимые для проекта (т.е. зависимости нашего проекта и их зависимости), имели загружаться вручную и указываться в сценарии сборки.

С другой стороны, mockito-core.jar - это просто классы Mockito (также с переупакованными ASM и CGLIB). При использовании с Maven или Gradle необходимые зависимости (Hamcrest и Objenesis) управляются этими инструментами (загружаются автоматически и помещаются в тестовый путь к классам). Это позволяет переопределить используемые версии (например, если в наших проектах используется никогда, но обратно совместимая версия), но, что более важно, эти зависимости не скрыты внутри mockito-all.jar, что позволяет обнаруживать возможную несовместимость версий с инструментами анализа зависимостей. Это гораздо лучшее решение, когда в проекте используется инструмент, управляемый зависимостями.

person Pasha    schedule 06.01.2019

Это сработало для меня. Не нужно ничего исключать. Я просто использовал mockito-core вместо 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'
person Joni Lappalainen    schedule 14.08.2019

Для jUnit 4.12 мою проблему устранила следующая комбинация зависимостей.

<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>
person Udara Seneviratne    schedule 30.03.2021