【发布时间】:2013-04-05 11:40:18
【问题描述】:
NoSuchMethodError 的另一个实例,用于 JUnit 和 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:
按照Garrett Hall 在answer 到Getting "NoSuchMethodError: org.hamcrest.Matcher.describeMismatch" when running test in IntelliJ 10.5 中的建议,pom 包含对 Hamcrest-library 1.3、Hamcrest-core 1.3 和 JUnit 4.11 的显式依赖(按此顺序)
根据 JUnit 文档,JUnit 4.11 Maven 依赖不再包括已编译的 Hamcrest 类,而是依赖于 Hamcrest-core 1.3;所以
NoSuchMethodError不应该出现。按照Dan 在answer 到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?
【问题讨论】:
标签: maven junit junit4 maven-surefire-plugin hamcrest