我使用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 */
}
}
当使用Ant从命令行运行时,它工作得非常好。但是当从IntelliJ运行时,它失败了:
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)
at com.netflix.build.MyTest.testmyStuff(MyTest.java:40)
我猜它使用了错误的hamcrest.MatcherAssert。我怎么找到哪个hamcrest ?它正在使用的MatcherAssert(即它正在使用哪个jar文件hamcrest.MatcherAssert)?AFAICT,我的类路径中唯一的hamcrest jars是1.3.RC2。
IntelliJ IDEA是否使用自己的JUnit或Hamcrest副本?
如何输出IntelliJ正在使用的运行时CLASSPATH ?
我有一个gradle项目,当我建立。Gradle依赖项部分如下所示:
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”。
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'
}
mockito-all和mockito-core之间的解释可以在这里找到:
https://solidsoft.wordpress.com/2012/09/11/beyond-the-mockito-refcard-part-3-mockito-core-vs-mockito-all-in-mavengradle-based-projects/
mockito-all.jar besides Mockito itself contains also (as of 1.9.5) two
dependencies: Hamcrest and Objenesis (let’s omit repackaged ASM and
CGLIB for a moment). The reason was to have everything what is needed
inside an one JAR to just put it on a classpath. It can look strange,
but please remember than Mockito development started in times when
pure Ant (without dependency management) was the most popular build
system for Java projects and the all external JARs required by a
project (i.e. our project’s dependencies and their dependencies) had
to be downloaded manually and specified in a build script.
On the other hand mockito-core.jar is just Mockito classes (also with
repackaged ASM and CGLIB). When using it with Maven or Gradle required
dependencies (Hamcrest and Objenesis) are managed by those tools
(downloaded automatically and put on a test classpath). It allows to
override used versions (for example if our projects uses never, but
backward compatible version), but what is more important those
dependencies are not hidden inside mockito-all.jar what allows to
detected possible version incompatibility with dependency analyze
tools. This is much better solution when dependency managed tool is
used in a project.