IT이야기

"NoSuchMethodError: org.hamcrest"를 가져옵니다.Matcher.descriptMismatch" (IntelliJ 10.5에서 테스트 실행 시)

cyworld 2022. 6. 30. 23:29
반응형

"NoSuchMethodError: org.hamcrest"를 가져옵니다.Matcher.descriptMismatch" (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 */
    }
}

명령줄에서 앤트를 사용하여 실행하면 완벽하게 작동합니다.그러나 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)

햄크레스트를 잘못 사용하고 있는 것 같아요.매처 어서트햄레스트를 어떻게 찾죠?사용하고 있는 Matcher Assert(햄크레스트에 사용하는 jar 파일)매처 어서트)AFAICT, 우리 반에서 햄크레스트 항아리는 1.3밖에 없어.RC2.

IntelliJ IDEA는 JUnit 또는 Hamcrest의 자체 복사본을 사용하고 있습니까?

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

햄크레스트 병이 JUnit 병보다 Import 오더 위에 있는지 확인합니다.

JUnit에는 자체 사양이 있습니다.org.hamcrest.Matcher대신 사용되고 있을 가능성이 있는 클래스입니다.

junit-dep-4.10.jar를 다운로드하여 대신 사용할 수도 있습니다.junit은 햄크레스트 클래스가 없는 JUnit입니다.

mockito에는 햄크레스트 클래스도 있기 때문에 이동해야 할 수도 있습니다.

이 문제는 이미 권장되지 않는 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>

는 것이었어요.hamcrest.Matcher 아니라, 이에요.hamcrest.MatcherAssert 그것은 내 의존관계 중 하나가 지정한 4.8 의존관계에서 끌어오고 있었다.

테스트 중에 어떤 소스로부터 어떤 종속성(및 버전)이 포함되어 있는지 확인하려면 다음을 수행합니다.

mvn dependency:tree -Dscope=test

다음은 현재 가장 정확할 것입니다.주의: junit 4.11은 햄크레스트 코어에 의존하기 때문에 mockito-all은 햄크레스트 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>

이게 조금 힘들었던 저에게 효과가 있었어요.

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

오래된 스레드인 것은 알지만 문제를 해결한 것은 다음 사항을 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'

해라

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

대신

expectMessage(message)

.ExpectedException★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

2020년 7월 현재 다음과 같은 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>

이 4.13 Junit 라이브러리와 햄크레스트에서는 햄크레스트를 사용합니다.어설션 및 예외 발생 시 MatcherAssert - 여기에 이미지 설명을 입력합니다.

이것은 매우 오래된 질문이고 아마도 앞서 말한 많은 아이디어들이 많은 문제를 해결했을 것이라는 사실에도 불구하고, 저는 여전히 제 문제를 해결한 해결책을 커뮤니티와 공유하고 싶습니다.

JSON-Array에 특정 아이템이 포함되어 있는지 여부를 확인하기 위해 사용하던 "hasItem"이라는 기능이 문제임을 알게 되었습니다.내 경우 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));

이것이 최선의 해결책은 아닐 수도 있지만, 데이터 유형이 잘못되었거나 불분명하기 때문에 예외가 발생할 수도 있습니다.

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-allmockito-core의 설명은 https://solidsoft.wordpress.com/2012/09/11/beyond-the-mockito-refcard-part-3-mockito-core-vs-mockito-all-in-mavengradle-based-projects/에서 확인할 수 있습니다.

Mockito 자체 외에 mockito-all.jar에는 다음 2개의 종속성이 포함되어 있습니다(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 내에 숨겨져 있지 않다는 것입니다.이것에 의해 의존성 분석 툴과의 비호환성이 검출될 가능성이 있습니다.프로젝트에서 종속성 관리 도구를 사용하는 경우 이 솔루션이 훨씬 더 좋습니다.

저 같은 경우에는 오래된 햄레스트를 유니트 빈티지에서 제외해야 했습니다.

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

이건 나한테 효과가 있었어.아무것도 제외할 필요가 없습니다.그냥 사용했어요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'

나에게 효과가 있었던 것은 햄크레스트 그룹을 junit 테스트 컴파일에서 제외하는 것이었습니다.

다음은 내 build.gradle의 코드입니다.

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

IntelliJ 를 사용하고 있는 경우는, 실행이 필요하게 되는 경우가 있습니다.gradle cleanIdea idea clean build의존성을 다시 검출합니다.

그게 최선의 답이 아닌 건 알지만, 만약 네가 클래스 패스를 제대로 작동하지 않는다면, 이건 플랜 B의 해결책이야.

테스트 클래스 패스에 descriptMismatch 메서드의 디폴트 구현으로 다음 인터페이스를 추가했습니다.

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

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>

언급URL : https://stackoverflow.com/questions/7869711/getting-nosuchmethoderror-org-hamcrest-matcher-describemismatch-when-running

반응형