Hamcrest 1.3和JUnit 4.11的NoSuchMethodError

Kas*_*erg 42 junit hamcrest junit4 maven maven-surefire-plugin

NoSuchMethodErrorJUnit和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();
        } } ));
Run Code Online (Sandbox Code Playgroud)

IndexerTest.java中的注释行152-157 (commit 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)
Run Code Online (Sandbox Code Playgroud)

设置:

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

背景:

A NoSuchMethodError是由调用非现有方法的(已编译)类引起的.describeMismatchJUnit + Hamcrest组合的特定情况通常是由JUnit中包含的Hamcrest类与Hamcrest库中的那些类的版本之间的不兼容引起的.

尝试解决NoSuchMethodError:

  • 聚甲醛包含Hamcrest库1.3,Hamcrest芯1.3,和JUnit 4.11的显式依赖,(按顺序)所建议加勒特厅答复获取:在运行测试时,"的NoSuchMethodError org.hamcrest.Matcher.describeMismatch" IntelliJ 10.5

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

  • 检查依赖关系树mvn dependency:tree,通过建议回答JUnit和hamcrest声明显示了Hamcrest 1.3和JUnit 4.11,无其他依赖于这些文件的显式依赖项(见http://db.tt/C2OfTDJB为完整的输出).

  • 在另一个测试中NoSuchMethodError,使用以下方法避免:

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

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

    assertThat(
        "Zylab detector not available",
        d.getDetectors(),
        hasItem(isA(ZylabMetadataDetector.class));
    
    Run Code Online (Sandbox Code Playgroud)

    我不确定是否使用显式类型参数<Detector>,instanceOf而不是使用isAHamcrest的显式引用Matchers,或者是那些避免使用的组合NoSuchMethodException; 在摆弄并尝试不同的东西后,它起作用了.

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

  • 使用派生的类BaseMatcherFeatureMatcher不是解决/避免错误.

想法如何解决NoSuchMethodError

小智 26

这个博客帮我解决了同样的问题:

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>
Run Code Online (Sandbox Code Playgroud)

  • 排除对我没有帮助,但lib的顺序有所帮助:hamcrest依赖(库)应该在Junit和/或Mockito依赖之前 (8认同)
  • 注意!你不能使用mockito-all,因为它里面有hamcrest(1.1),而不是依赖.相反,使用mockito-core和teh hamcrest-core排除.您不需要从junit 4.11中排除hamcrest,因为这取决于hamcrest 1.3,仅在早期的junit版本上. (8认同)