Hamcrest测试总是失败。

52
我正在使用 hamcrest 1.3 来测试我的代码。它只是一个骰子。我试图测试它以确保生成的数字小于13。我有一个打印语句,打印生成的数字是多少。生成的数字总是小于13,但测试总是失败。我做错了什么吗?
这是我正在测试的代码。
import java.util.Random;

public class Die {
    private int numSides;
    Random rand;

    public Die(int numSides){
        this.numSides = numSides;
        rand = new Random(System.currentTimeMillis());
    }

    public int roll(){
        return rand.nextInt(numSides) + 1;
    }
}

这是我的测试代码。

import static org.hamcrest.Matchers.*;
import static org.hamcrest.MatcherAssert.assertThat;

import org.junit.Test;

public class DieTest {
    @Test
    public void testRoll() {
        Die x = new Die(12);    
        assertThat(x.roll(), is(lessThan(13)));
    }
}

编辑:这是失败的堆栈跟踪。

java.lang.SecurityException: class "org.hamcrest.Matchers"'s signer information does not match signer information of other classes in the same package
at java.lang.ClassLoader.checkCerts(Unknown Source)
at java.lang.ClassLoader.preDefineClass(Unknown Source)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at DieTest.testRoll(DieTest.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

对我来说很好用。请注意,这只测试了一次掷骰子,显然并没有太大帮助。(稍微撤回一下;如果我将值更改为8并获得更高的点数,则在使用1.3.0RC2时会出现Hamcrest错误。您使用的是哪个版本?) - Dave Newton
顺便提一下,你的代码将以相等的概率生成从1到12的每个数字。但是,如果你掷两个标准骰子,不同的数字会以不同的概率出现(7最有可能,2和12最不可能,1不可能)。因此,如果这就是你想模拟的情况,那么你的代码是不准确的。 :) - Tyler
能否发布错误的堆栈跟踪? - Stefan Birkner
1
我正在使用1.3.0RC2版本。感谢MatrixFrog,我甚至没有想到过这一点。 - beachw08
Maven用户是否仍然存在这个问题?! - Hedrack
@DusanVasiljevic 我解决了这个问题,包括在pom中添加hamcrest库并从构建路径中删除Eclipse的JUnit库。 - zer0uno
24个回答

78

6
重要的是记住(一开始可能不太清楚)在“顺序和导出”选项卡中,Hamcrest(或JMock)必须在JUnit之前,而不是在“库”中。 - Schultz9999
12
我正在使用Maven,即使我在pom.xml中将hamcrest的jar包列在JUnit之前,但Eclipse似乎仍在使用其内置的 JUnit/Hamcrest jar包,所以我仍然会收到“签名者信息不匹配”的错误。在Eclipse之外运行'mvn test'没有错误。上面的链接并未提及Maven。有什么提示或帮助可以让Eclipse JUnit runner正常工作吗? - djb
2
我和dbj(上面的帖子)处于同样的困境。我们的项目使用Eclipse和Maven,出于上述原因,我一直无法解决这个问题。我花了几个小时寻找解决方案,但从未找到。然而,在我寻找更好的断言机制时,我发现了FEST-ASSERT。我认为它比Hamcrest更好,所以我的问题现在得到解决了(虽然不是我最初打算的方式)。 - Robert Patterson
1
这并没有帮助我。我正在使用rest-assured 3.0.3,导入eclipse JUnit 4会导致上述错误。为了解决这个问题,我在我的pom.xml中添加了一个进一步的依赖项,即JUnit(4.4)本身,而不是使用Run As - JUnit test,现在我运行Maven test - 这完美地解决了问题。 - Timothy Dalton
2
懒人专用链接:简单解决方法:将 $ECLIPSE_HOME\plugins\org.hamcrest.core_1.3.0.v201303031735.jar 替换为 Maven hamcrest-core-1.3.jar(显然需要将其重命名为与 Eclipse jar 相同的名称)。 - lmo
显示剩余3条评论

19

我刚从项目配置中删除了JUnit库。但是我仍然可以运行测试,因为JUnit也包含在我的pom文件中。因此,解决方案只需使用来自Maven的库。


这对我很有帮助。出于某种原因,即使椭圆的junit4在maven库下,它也无法工作。 - user5692355
这就是解决我的问题的方法。在项目构建路径中,我既将JUnit作为单独的库引入,又将其作为Maven依赖项下的jar引入。一旦我删除了该库,问题就消失了。 - Kate Barnett

14
在我的Eclipse项目设置中的Java Build Path部分,Libraries中我之前添加了一个内部的JUnit库,使用的是JUnit版本4.8和hamcrest-core版本1.1。我相信这是导致我的问题的原因。
我将这些信息留在这里,也许其他人会从我的经验中受益。

1
这就是我的情况!谢谢。 - Sagar
1
在使用Maven项目的Eclipse中容易犯的错误。 - ayahuasca
是的,从我的构建路径中移除Junit 4可以解决这个问题。 - Saddam Hussain

11

如果您正在使用Maven项目,只需从构建路径中删除Junit库,并通过POM单独引入Junit和Hamcrest即可。


这对我有用。错误是因为我使用的ArrayList符号(java.util)不匹配。 - FonzTech
这对我也起作用了。它简单、简明,并且不会干扰核心JAR文件。 - gourabix

6

使用junit-dep.jar而不是junit.jar- 这是没有依赖关系的JUnit版本。Junit.jar包含一个旧版本的Hamcrest。


3
自 JUnit 4.11 版本开始,junit.jar 已不再包含 hamcrest 类。junit-dep.jar 已经被弃用。详见 https://github.com/junit-team/junit/wiki/Use-with-Maven。 - leo

4

首先,确保您在POM.xml文件中添加了JUnit依赖项。

现在,右键单击项目并转到属性,选择Java构建路径,然后选择库选项卡。

在我的情况下,有Maven依赖项、JRE和Junit4库。我只删除了Junit库,这对我起作用了。或者,也可以重新排序库,因为由于Hamcrest和JUnit4的构建顺序,问题会出现。


4
Johan Mark(上述)建议将文件$ ECLIPSE_HOME \ plugins \ org.hamcrest.core_1.3.0.v201303031735.jar重命名为* .bak 或删除该文件。 重命名/删除文件导致我的Eclipse JUnit库停止工作,但使用与我的Maven存储库中同一版本的JAR文件副本替换JAR文件使证书问题消失。 (正如Google上的某人所说,Eclipse JUnit hamcrest副本存在证书问题,但Maven副本没有...)

3

如果您正在使用Maven:

步骤:

  1. 这里将最新的Hamcrest依赖项添加到POM中。

  2. 这里将最新的JUnit依赖项添加到POM中。

  3. 从构建路径中删除任何JUnit库。

如此展示:

这里

和这里

  1. 完成以上所有步骤后,刷新您的项目并运行。

1
在我的情况下,使用hamcrest-all而不是hamcrest-library是解决方案。 - Robert

2

我曾经遇到过同样的问题。 右键单击项目 / Order and Export / 将您的hamcrest库移到第一个位置,由于某种原因,它必须在Junit库之前。


嗨,你的回答非常特定于正在使用的IDE。更详细地解释你正在做什么(例如通过更改依赖项顺序...)将非常有用,这样任何不使用与你相同IDE的人仍然可以从你的回答中受益。 :) - saywhatnow

2
我遇到了同样的异常。像beachw08建议的那样,我参考了:

http://code.google.com/p/hamcrest/issues/detail?id=128

其中一篇帖子说:
将文件$ECLIPSE_HOME\plugins\org.hamcrest.core_1.3.0.v201303031735.jar重命名为类似*.bak的文件或删除该文件。
我这样做就解决了我的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接