Java 获得;NoSuchMethodError:org.hamcrest.Matcher.DescribeMatchs“;在IntelliJ 10.5中运行测试时

Java 获得;NoSuchMethodError:org.hamcrest.Matcher.DescribeMatchs“;在IntelliJ 10.5中运行测试时,java,junit,intellij-idea,junit4,hamcrest,Java,Junit,Intellij Idea,Junit4,Hamcrest,我正在使用JUnit dep 4.10和Hamcrest 1.3.RC2 我创建了一个自定义匹配器,如下所示: public static class MyMatcher extends TypeSafeMatcher<String> { @Override protected boolean matchesSafely(String s) { /* implementation */ } @Override public v

我正在使用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 */
    }
}
我猜它用错了hamcrest.matcherasert。如何找到它使用的hamcrest.matcherasert(即它使用的hamcrest.matcherasert的jar文件)?目前,我的类路径中唯一的hamcrest JAR是1.3.RC2

IntelliJ IDEA是否使用自己的JUnit或Hamcrest副本


如何输出IntelliJ使用的运行时类路径?

确保导入顺序中的hamcrestjar高于您的JUnitjar

JUnit自带了自己的
org.hamcrest.Matcher
类,该类可能会被替代使用

您还可以下载并使用junit-dep-4.10.jar,它是没有hamcrest类的junit


mockito中也有hamcrest类,因此您可能还需要对其进行移动/重新排序

问题是使用了错误的
hamcrest.Matcher
,而不是
hamcrest.matcherasert
,类。这是从junit-4.8依赖项中拉入的,我的一个依赖项正在指定

要查看测试时来自哪个源的依赖项(和版本),请运行:

mvn依赖关系:树-Dscope=test

当类路径上有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>

org.hamcrest
汉克雷斯特岩芯
1.3
测试
org.hamcrest
汉克雷斯特图书馆
1.3
测试
org.mockito
莫基托所有
1.9.5
测试
朱尼特
朱尼特
4.11
测试

这在我挣扎了一段时间后奏效了


org.hamcrest
汉克雷斯特酒店
1.3
测试
org.mockito
莫基托所有
1.9.5
测试
朱尼特
朱尼特
4.11
测试

以下内容今天应该是最正确的。注意,JUnit4.11依赖于hamcrest内核,所以您根本不需要指定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>

朱尼特
朱尼特
4.11
测试
org.mockito
莫基托磁芯
1.10.8
测试
org.hamcrest
汉克雷斯特岩芯
试试看

expect(新的ThrowableMessageMatcher(新的StringContains(message)))

而不是

expectMessage(消息)


您可以编写自定义的
ExpectedException
或实用程序方法来包装代码。

对我有效的方法是将hamcrest组从junit测试编译中排除

以下是my build.gradle中的代码:

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

如果您正在运行IntelliJ,则可能需要运行
gradle cleanIdea clean build
来再次检测依赖项

我知道这不是最好的答案,但是如果你不能让类路径工作,这是一个B计划解决方案

在我的测试类路径中,我为DescribeMatch方法添加了以下带有默认实现的接口

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_();
}
package org.hamcrest;
/**
*修补程序,因为类路径有问题。Hamcrest应高于Mockito,以便BaseMatcher
*实现了DescribeMatch方法,但它不适用于我。
*/
公共接口匹配器扩展自描述{
布尔匹配(对象项);
默认无效描述不匹配(对象项、描述不匹配描述){
描述不匹配。appendDescriptionOf(this)。appendValue(item);
}
@不赞成
void(不)实现(匹配器)(而是)扩展(BaseMatcher)();
}

我知道这是一个旧线程,但对我来说,解决问题的方法是在build.gradle文件中添加以下内容。 如上所述,
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'
可能有用:


尽管这是一个非常古老的问题 也许前面提到的许多想法解决了许多问题, 我仍然想与解决我问题的社区分享解决方案

我发现问题出在一个名为“hasItem”的函数上 我用它来检查JSON数组是否包含特定项。 在我的例子中,我检查了Long类型的值

这就导致了这个问题

不知何故,匹配器在Long类型的值方面存在问题。 (我不使用JUnit或Rest Assured这么多idk。确切的原因是, 但我猜返回的JSON数据只包含整数。)

因此,我所做的实际修复问题如下。 而不是使用:

long ID = ...;

...
.then().assertThat()
  .body("myArray", hasItem(ID));
您只需将其转换为整数。 工作代码如下所示:

long ID = ...;

...
.then().assertThat()
  .body("myArray", hasItem((int) ID));
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'
}
这可能不是最好的解决方案,
但我只想指出,由于数据类型错误/未知,也可能引发异常。

我有一个gradle项目,当我的build.gradle dependencies部分如下所示时:

long ID = ...;

...
.then().assertThat()
  .body("myArray", hasItem((int) ID));
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”

mockito all和mockito core之间的解释如下:

mockito-all.jar除了mockito本身之外还包含(从1.9.5开始)两个 依赖项:Hamcrest和Objenesis(让我们省略重新打包的ASM和 CGLIB一会儿)。原因是拥有所需的一切 在一个JAR中,将其放在类路径上。它可能看起来很奇怪, 但请记住,Mockito开发始于 纯Ant(没有依赖关系管理)是最流行的构建 Java项目系统和 项目(即我们项目的依赖项及其依赖项)已 手动下载并在生成脚本中指定

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