JUnit & Hamcrest 组合的另一个实例NoSuchMethodError
。违规代码:
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
- 汉克雷斯特 1.3
- 使用 Maven 的 surefire 插件(2.14 版),该插件使用其 JUnitCoreProvider
- Java 7 (OpenJDK)
- 参见pom(提交ac72ce)
背景:
ANoSuchMethodError
是由调用不存在的方法的(编译的)类引起的。JUnit + Hamcrest 组合的具体情况describeMismatch
通常是由 JUnit 中包含的 Hamcrest 类与 Hamcrest 库中这些类的版本之间的不兼容引起的。
解决 NoSuchMethodError 的尝试:
pom 包含对 Hamcrest-library 1.3、Hamcrest-core 1.3 和 JUnit 4.11 的显式依赖(按此顺序),正如Garrett Hall在运行测试时在回答Getting "NoSuchMethodError: org.hamcrest.Matcher.describeMismatch" 时所建议的那样智能 10.5
根据 JUnit 文档,JUnit 4.11 Maven 依赖不再包括已编译的 Hamcrest 类,而是依赖于 Hamcrest-core 1.3;所以不
NoSuchMethodError
应该发生。按照Dan在回答junit 和 hamcrest 声明时的
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 (commit ac72ce ) 的第 120–123 行,而不是更明显的:
assertThat( "Zylab detector not available", d.getDetectors(), hasItem(isA(ZylabMetadataDetector.class));
我不确定显式类型参数
<Detector>
,使用instanceOf
而不是isA
,对 Hamcrest 的显式引用Matchers
,或者这些的组合避免了NoSuchMethodException
; 在摆弄并尝试不同的事情之后,它起作用了。使用显式类型参数并不能解决/避免错误。
使用派生自的类
BaseMatcher
而不是FeatureMatcher
没有解决/避免错误。