Hamcrest 1.3& NoSuchMethodError JUnit 4.11

时间:2013-04-05 11:40:19

标签: maven junit junit4 maven-surefire-plugin hamcrest

JUnit&的NoSuchMethodError的另一个实例Hamcrest组合。 违规代码:

assertThat(dirReader.document(0).getFields(), hasItem(
    new FeatureMatcher<IndexableField, String>(equalTo("Patisnummer"), "Field key", "Field key") {
        @Override
        protected String featureValueOf(IndexableField actual) {
            return actual.name();
        } } ));

IndexerTest.java中的注释行152-157(提交ac72ce

导致NoSuchMethodError(请参阅http://db.tt/qkkkTE78获取完整输出):

java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V
at org.hamcrest.FeatureMatcher.matchesSafely(FeatureMatcher.java:43)
at org.hamcrest.TypeSafeDiagnosingMatcher.matches(TypeSafeDiagnosingMatcher.java:55)
at org.hamcrest.core.IsCollectionContaining.matchesSafely(IsCollectionContaining.java:25)
at org.hamcrest.core.IsCollectionContaining.matchesSafely(IsCollectionContaining.java:14)
at org.hamcrest.TypeSafeDiagnosingMatcher.matches(TypeSafeDiagnosingMatcher.java:55)
at org.junit.Assert.assertThat(Assert.java:770)
at org.junit.Assert.assertThat(Assert.java:736)
at indexer.IndexerTest.testIndexContainsField(IndexerTest.java:152)

设置:

  • JUnit 4.11
  • Hamcrest 1.3
  • 使用Maven的surefire插件(版本2.14),它使用其JUnitCoreProvider
  • Java 7(OpenJDK)
  • 请参阅pom(提交ac72ce

背景:

NoSuchMethodError是由调用非现有方法的(已编译)类引起的。 describeMismatch和JUnit + Hamcrest组合的具体情况通常是由JUnit中包含的Hamcrest类与Hamcrest库中这些类的版本之间的不兼容引起的。

尝试解决NoSuchMethodError:

  • pom包含对Hamcrest-library 1.3,Hamcrest-core 1.3和JUnit 4.11(按此顺序)的显式依赖,正如Garrett Hall answerGetting "NoSuchMethodError: org.hamcrest.Matcher.describeMismatch" when running test in IntelliJ 10.5所建议的那样}}

  • 根据JUnit文档,JUnit 4.11 Maven依赖项不再包含已编译的Hamcrest类,而是依赖于Hamcrest-core 1.3;所以NoSuchMethodError不应该出现。

  • 按照Dananswer junit and hamcrest declaration的建议,使用mvn dependency:tree检查依赖关系树,显示Hamcrest 1.3和JUnit 4.11的显式依赖关系,没有其他依赖关系这些文件(完整输出见http://db.tt/C2OfTDJB)。

  • 在另一项测试中,使用以下内容避免使用NoSuchMethodError

    assertThat(
        "Zylab detector not available",
        d.getDetectors(),
        hasItem(Matchers.<Detector>instanceOf(ZylabMetadataXmlDetector.class)));
    

    IndexerTest.java的第120-123行(提交ac72ce) 而不是更明显的:

    assertThat(
        "Zylab detector not available",
        d.getDetectors(),
        hasItem(isA(ZylabMetadataDetector.class));
    

    我不确定使用<Detector>而不是instanceOf的显式类型参数isA,对Hamcrest的Matchers的显式引用,还是那些避免使用的组合NoSuchMethodException;在摆弄并尝试不同的事情后,它起作用了。

  • 使用显式类型参数无法解决/避免错误。

  • 使用从BaseMatcher而非FeatureMatcher派生的类无法解决/避免错误。

想法如何修复NoSuchMethodError

8 个答案:

答案 0 :(得分:24)

此博客帮助我解决了同样的问题:

https://tedvinke.wordpress.com/2013/12/17/mixing-junit-hamcrest-and-mockito-explaining-nosuchmethoderror/

在Mockito和Junit的依赖项中,作者添加了排除:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <exclusions>
        <exclusion>
            <artifactId>hamcrest-core</artifactId>
            <groupId>org.hamcrest</groupId>
        </exclusion>
    </exclusions>
</dependency>

答案 1 :(得分:2)

也许其中一个其他JAR拥有较旧版本的Hamcrest MatcherBaseMatcher。这是一个list of JARs,其中包括后者,但我不知道该网站有多全面。是否有Maven插件会向您显示包含类似于依赖树的类的所有依赖项?

答案 2 :(得分:2)

使用David's提示和How do I split a string on a delimiter in Bash?会产生以下bash脚本:

( IFS=":"; for i in `mvn dependency:build-classpath | grep -v '\[INFO\]'`; do jar tf $i | awk "{print \"$i\\t\" \$1}"; done | grep Matcher )

(在http://www.kaspervandenberg.net/2013/scripts/findDependencyClass.sh在线)

发现依赖项JGlobus-Core-2.0.4有自己的org.hamcrest.BaseMatcherorg.hamcrest.CoreMatchersorg.hamcrest.Matcher版本。

答案 3 :(得分:2)

如果您使用的是Eclipse,“打开类型”工具(CTRL + SHIFT + T)可以帮助您找到有问题的包。只需搜索类名(例如,描述),来自不同JAR的同一类的多次出现都是红色标记。

答案 4 :(得分:2)

对我有用的是重新排序依赖项。 而不是去mockito,junit, 我不得不把junit,mockito。

Mockito 1.9.5使用hamcrest 1.1,它不兼容并导致问题。

答案 5 :(得分:0)

如果您使用的是Eclipse: 对我来说,在eclipse-&gt;项目属性 - &gt; Java构建路径 将mockito-all-1.9.5.jar移到&#39; Order and Export&#39;的底部。列表做了伎俩。就在上面我有junit-4.11.jar以及那个hamcrest-core-1.3.jar

答案 6 :(得分:0)

我使用以下代码在jar hell项目中解决了此Gradle问题:

    testCompile (group: 'junit', name: 'junit', version: '4+') {
        exclude group: 'org.hamcrest'
    }
    testCompile ('org.mockito:mockito-core:1+') {
        exclude group: 'org.hamcrest'
    }
    testCompile 'org.hamcrest:java-hamcrest:2.0.0.0'

答案 7 :(得分:0)

对于使用Gradle作为构建工具的项目:

testCompile("junit:junit:4.11") {
     exclude group: 'org.hamcrest', module: 'hamcrest-core'
     exclude group: 'org.hamcrest', module: 'hamcrest-library' 
}
testCompile group: 'org.hamcrest', name: 'hamcrest-core', version: '1.3'
testCompile group: 'org.hamcrest', name: 'hamcrest-library', version: '1.3'