IntelliJ 10.5에서 테스트를 실행할 때“NoSuchMethodError : org.hamcrest.Matcher.describeMismatch”가 표시됨


233

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를 사용하고 있다고 생각합니다. 사용중인 hamcrest.MatcherAssert를 어떻게 찾습니까 (예 : hamcrest.MatcherAssert에 사용중인 jar 파일)? AFAICT, 클래스 경로에서 유일한 햄 크레스트 병은 1.3.RC2입니다.

IntelliJ IDEA는 자체 JUnit 또는 Hamcrest 사본을 사용합니까?

IntelliJ가 사용하는 런타임 CLASSPATH를 어떻게 출력합니까?

답변:


272

hamcrest jar가 JUnit jar 보다 가져 오기 순서에서 더 높은지 확인하십시오 .

JUnit 에는 org.hamcrest.Matcher대신 사용되는 자체 클래스가 있습니다.

또한 hamcrest 클래스가없는 JUnit 인 junit-dep-4.10.jar을 다운로드하여 사용할 수도 있습니다.

mockito에는 햄 크레스트 클래스도 포함되어 있으므로 이동 / 재주문해야 할 수도 있습니다.


1
OP는 이미 '-dep-'jar을 사용하고 있다고 말했다. 그러나 JUnit jar의 Matcher 클래스를 사용하고 있다고 생각합니다. 아마도 IDE가 자체 JUnit 사본을 사용하고있을 것입니다.
MatrixFrog

2
IntelliJ의 junit.jar 및 junit-4.8.jar 사본을 제거하고 junit-dep-4.10.jar을 IntelliJ의 lib / 디렉토리에 설치했는데 문제가 계속 발생합니다.
Noel Yap

8
JUnit 4.11은 Hamcrest 1.3과 호환되며 JUnit 4.10은 Hamcrest 1.1과 호환 됩니다. search.maven.org/remotecontent?filepath=junit/junit-dep/4.10/…
Muthu

23
mockito-all을 사용하지 말고 hamcrest를 제외한 mockito-core를 사용하십시오.
Ulf

1
사무실에서 오후 7시 33 분입니다. 휴가 전에 외출하기 전에 반드시 제공해야하는 중요한 기능에 대해 작업 중이며 금요일입니다. 다음 주에 그 휴가에 있습니다 !!!!!! 내가 어떻게이 오류를 지금 얻을 수 있겠 어!
Adelin

170

이 문제 는 이미 사용되지 않는 클래스 경로에 mockito-all 이있는 경우에도 발생합니다 .

가능하면 mockito-core 만 포함 하십시오 .

junit, mockito 및 hamcrest를 혼합하기위한 Maven 구성 :

<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의 새로운 버전에는 powermock과 동일한 hamcrest가 포함되어 있습니다!
Tom Parkinson

3
그것이 mockito-all 대신 mockito-core 여야합니까?
user944849

3
당신이 모든 속도로 필요한 경우에만 코어를 포함 할 수 있지만 위의 모든 경우에 작동해야합니다. 의존성의 순서는 중요 비트 mvn 3이 우선 순위 순으로 맨 처음부터 시작합니다.
Tom Parkinson

3
대신 mockito 코어를 포함하고 (모든에서 할 수없는) 그것에서 hancrest 제외, mockito은 모두 그 이후는 1.1 hamcrest 포함하면 안됩니다
울프 린드 백

1
"가능한 경우 mockito-core 만 포함하십시오." 그렇다면 왜이 답변은 여전히 ​​mockito-all을 사용합니까?
스텔스 랍비

60

문제는 잘못이 있다고했다 hamcrest.Matcher,하지 hamcrest.MatcherAssert, 클래스가 사용되었다. 그것은 junit-4.8 의존성에서 가져온 것입니다. 내 의존성 중 하나가 지정했습니다.

테스트하는 동안 어떤 소스에서 어떤 종속성 (및 버전)이 포함되는지 확인하려면 다음을 실행하십시오.

mvn dependency:tree -Dscope=test

5
나는 같은 문제가 있었다. 나는 JUnit-dep과 Hamcrest-core를 사용하고 있었지만 Powermock이 pom에 일찍 나열되어 JUnit-dep과 Hamcrest 이전에 JUnit이 포함되었습니다.
John B

9
또한 mockito-all에는 일부 Hamcrest 클래스가 포함됩니다. mockito-core를 사용하고 hamcrest 의존성을 배제하는 것이 좋습니다.
Brambo

3
똑같은 문제가 발생했습니다. 해결책은 junit 버전을 4.11로 올리면서 hamcrest 1.3과 호환되는 (즉, "클래스 포함") 1.3
r3mbol

모든 제안이 제대로 작동하지 않는 사람들 (종속성 순서, 제외, 바꾸기 -all로 바꾸기 -core등) : hamcrest를 버전 1.1로 다시 변경해야했고 이제 모든 것이 다시 작동합니다.
Felix Hagspiel

1
내 수입을 변경에 때 나를 위해이 일 import static org.mockito.Matchers.anyString;에서import static org.mockito.ArgumentMatchers.anyString;
Shrikant 프라 부

28

다음은 오늘 가장 정확해야합니다. junit 4.11은 hamcrest-core에 의존하므로 hamcrest 1.1이 포함되어 있기 때문에 mockito-all을 전혀 사용할 수 없도록 지정할 필요는 없습니다.

<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는 이제 hamcrest-core 1.3에 의존합니다.
JeeBee

제외는 mockito-all나에게 도움이되었습니다 mockito-core. 또한 Mockito 전에 Hamcrest를 선언하여 pom.xml작업합니다.
Kirill

13

이것은 조금 고군분투 한 후에 나를 위해 일했습니다.

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

저도 마찬가지입니다. 이 순서에 의존성을두면 maven이 전 이적 뎁을 올바르게 해결하는 데 도움이됩니다. mockito-core 또는 mockito-all에서 hamcrest를 명시 적으로 배제하는 것이 누군가가 당신의 pom에서 뎁을 재정렬하는 경우 더 안전 할 수 있습니다.
Mat

4

시험

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

대신에

expectMessage(message)

ExpectedException코드를 마무리하기 위해 사용자 정의 또는 유틸리티 메소드를 작성할 수 있습니다 .


4

나는 이것이 오래된 스레드라는 것을 알고 있지만 나를 위해 문제를 해결 한 것은 내 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'

1

이것은 매우 오래된 질문이며 아마도 앞서 언급 한 많은 아이디어가 많은 문제를 해결했지만 여전히 내 문제를 해결 한 커뮤니티와 솔루션을 공유하고 싶습니다.

문제는 JSON 배열에 특정 항목이 포함되어 있는지 여부를 확인하는 데 사용하는 "hasItem"이라는 함수라는 것을 알았습니다. 필자의 경우 Long 유형의 값을 확인했습니다.

그리고 이것은 문제를 일으켰습니다.

어쨌든 Matchers는 Long 유형의 값에 문제가 있습니다. (JUnit 또는 Rest-Assured를 너무 많이 사용하지 않습니다. 정확히 이유는 있지만 반환 된 JSON 데이터에는 정수가 포함되어 있다고 생각합니다.)

실제로 문제를 해결하기 위해 수행 한 작업은 다음과 같습니다. 사용하는 대신:

long ID = ...;

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

당신은 정수로 캐스팅해야합니다. 따라서 작업 코드는 다음과 같습니다.

long ID = ...;

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

아마도 최선의 해결책은 아니지만 잘못된 / 알 수없는 데이터 유형으로 인해 예외가 발생할 수 있다고 언급하고 싶었습니다.


0

나를 위해 일한 것은 junit 테스트 컴파일에서 hamcrest 그룹을 제외하는 것이 었습니다.

내 build.gradle의 코드는 다음과 같습니다.

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

IntelliJ를 실행중인 경우 gradle cleanIdea idea clean build종속성을 다시 감지 하기 위해 실행해야 할 수도 있습니다 .


0

나는 이것이 최선의 대답은 아니라는 것을 알고 있지만 클래스 패스를 작동시킬 수 없다면 이것은 계획 B 솔루션입니다.

테스트 클래스 경로에서 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_();
}

0

나는 gradle 프로젝트를 가지고 있으며 build.gradle dependencies 섹션이 다음과 같이 보일 때 :

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-allmockito-core 사이의 설명은 여기에서 찾을 수 있습니다 : https://solidsoft.wordpress.com/2012/09/11/beyond-the-mockito-refcard-part-3-mockito-core-vs-mockito 복합기 기반 프로젝트 /

Mockito 자체 이외에도 mockito-all.jar에는 Hamcrest와 Objenesis라는 두 가지 종속성 (1.9.5 현재)이 포함되어 있습니다 (일시적으로 재 패키징 된 ASM 및 CGLIB를 생략하겠습니다). 그 이유는 하나의 JAR 안에 필요한 모든 것을 클래스 패스에 배치하기 위해서였습니다. 이상하게 보일 수 있지만, 의존성 관리가없는 순수한 Ant가 Java 프로젝트에 가장 인기있는 빌드 시스템이었고 프로젝트에 필요한 모든 외부 JAR (예 : 프로젝트의 종속성 및 종속성)이 있던시기에 Mockito 개발이 시작된 것을 기억하십시오. 수동으로 다운로드하여 빌드 스크립트에 지정해야합니다.

반면에 mockito-core.jar는 Mockito 클래스입니다 (리 패키지 된 ASM 및 CGLIB와 함께). Maven 또는 Gradle과 함께 사용할 때 필요한 종속성 (Hamcrest 및 Objenesis)은 해당 도구 (자동으로 다운로드하여 테스트 클래스 경로에 배치)에 의해 관리됩니다. 사용 된 버전을 재정의 할 수 있지만 (예를 들어 프로젝트에서 절대 호환되지 않는 이전 버전과 호환되는 경우) 종속성이 mockito-all.jar 안에 숨겨져 있지 않은 것이 중요합니다. 종속성 관리 도구를 프로젝트에서 사용할 때 훨씬 더 나은 솔루션입니다.


0

내 경우에는 junit-vintage에서 오래된 hamcrest를 제외해야했습니다.

<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

이것은 나를 위해 일했습니다. 아무것도 제외 할 필요가 없습니다. 방금 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'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.