我使用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.
尽管这是一个非常古老的问题
也许前面提到的许多想法解决了许多问题,
我仍然想与解决我的问题的社区分享解决方案。
我发现问题出在一个叫hasItem的函数上
我用它来检查json数组是否包含特定的项。
在我的例子中,我检查了类型为Long的值。
这就产生了问题。
不知何故,matcher在Long类型的值上有问题。
(我不太使用JUnit或Rest-Assured,所以idk。为什么,
但我猜返回的JSON-data只包含整数。)
为了解决这个问题,我做了如下的事情。
而不是使用:
long ID = ...;
...
.then().assertThat()
.body("myArray", hasItem(ID));
你只需要转换为Integer。
工作代码是这样的:
long ID = ...;
...
.then().assertThat()
.body("myArray", hasItem((int) ID));
这可能不是最好的解决方案,
但我只是想提一下,也可以因为错误/未知的数据类型而抛出异常。