Programing

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

lottogame 2020. 4. 21. 08:17
반응형

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


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를 어떻게 출력합니까?


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

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

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

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입니다. 그것은 junit-4.8 의존성에서 가져온 것입니다. 내 의존성 중 하나가 지정했습니다.

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

mvn dependency:tree -Dscope=test

다음은 오늘 가장 정확해야합니다. 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>

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

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

시험

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

대신에

expectMessage(message)

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


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

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

문제는 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));

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


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

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

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

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


나는 이것이 최선의 대답은 아니라는 것을 알고 있지만 클래스 패스를 작동시킬 수 없다면 이것은 계획 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_();
}

나는 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 안에 숨겨져 있지 않으므로 종속성 분석 도구로 가능한 버전 비 호환성을 감지 할 수 있습니다. 프로젝트에서 종속성 관리 도구를 사용할 때 훨씬 더 나은 솔루션입니다.


제 경우에는 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>

이것은 나를 위해 일했습니다. 아무것도 제외 할 필요가 없습니다. 방금 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'

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

반응형