与Mockito 1.10.17的java.lang.VerifyError

时间:2014-12-31 13:09:49

标签: java testng mockito jmock

我正在尝试用Mockito取代JMock(1.10.17)。我已经成功完成了一些单元测试,但现在我想使用超时功能

verify(publisher, timeout(5000)).notifySubscribers(any(BecameMasterMessage.class));

我得到了这个例外:

java.lang.VerifyError: (class: org/mockito/internal/verification/VerificationOverTimeImpl, method: verify signature: (Lorg/mockito/internal/verification/api/VerificationData;)V) Incompatible argument to function
    at org.mockito.verification.Timeout.<init>(Timeout.java:32)
    at org.mockito.verification.Timeout.<init>(Timeout.java:25)
    at org.mockito.Mockito.timeout(Mockito.java:2164)

问题发生在IntelliJ和Maven中。类路径上只有一个版本的Mockito。在类路径上还有JMock 2.5.1,我无法删除,因为此时99%的单元测试仍然使用JMock。我不知道这与它有什么关系。

更新:我尝试使用JMock 2.6.0和Hamcrest 1.3但结果是一样的。

更新2:

这有效:

Thread.sleep( 5000 );
verify( m_publisher ).notifySubscribers( any( BecameMasterMessage.class ) );

这不是:

verify(publisher, timeout(5000)).notifySubscribers(any(BecameMasterMessage.class));

更新3: 我做了一个具有完全相同问题的小型测试项目:请参阅https://github.com/wimdeblauwe/mockito-verify-problem并从IntelliJ或Maven运行它。

2 个答案:

答案 0 :(得分:5)

这里的问题是TestNG,JUnit和Mockto之间的一个不幸的星座。要解决您的问题,您只需要向JUnit 4.0或更高版本添加依赖项(最新版本当前为4.12):

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
</dependency>

以下是详细信息:

TestNG,显然是你的测试框架,声明了对相当旧的JUnit版本3.8.1的依赖。 Mockito根本没有声明对JUnit的依赖,但是它使用了JUnit 4.0(!)中引入的一些JUnit类。

修改

示例中的方法Mockito#timeout()会创建一个Timeout实例,该实例又会创建VerificationOverTimeImpl的实例。方法VerificationOverTimeImpl#verify()处理ArgumentsAreDifferent类型的错误,该类型是org.junit.ComparisonFailure的子类。

从JUnit版本3.8.1到4.x,ComparisonFailure的类层次结构更改为以AssertionError而不是Error作为基类。引发VerifiyError是因为VerificationOverTimeImpl#handleVerifyException()需要AssertionError,但在使用JUnit 3.8.1时将使用Error调用。

答案 1 :(得分:0)

编辑:看来stefan首先回答。他的诊断几乎是正确的,但是,org.mockito.exceptions.verification.junit.ArgumentsAreDifferent扩展junit.framework.ComparisonFailure,它存在于JUnit 3.x中,它是TestNG 5.x的依赖。 当JVM执行链接时,VerifyError本身可能需要做,因为JUnit 3.x和JUnit 4.x之间的ComparisonFailure类型本身发生了变化。

无论如何,Mockito中的问题是它使用了一个不应该使用的JUnit类。那个Mockito不再支持JUnit 3.x。

<强> TL; TR

我们在代码内部有一个问题,你正在使用的验证模式使用的是一个不在类路径上的JUnit类。在POM的依赖项中添加JUnit将解决问题。

感谢报道。我在GitHub (#152)

上创建了一个问题

长篇故事

出于某种原因,TestNG 5.xxx使JVM在VerifyError上失败,对于那时甚至没有被调用的方法。

java.lang.VerifyError: (class: org/mockito/internal/verification/VerificationOverTimeImpl, method: verify signature: 
   (Lorg/mockito/internal/verification/api/VerificationData;)V) Incompatible argument to function

但是切换到最新版本的TestNG,6.8。因为可理解的原因导致JVM失败:NoClassDefFoundError

java.lang.NoClassDefFoundError: junit/framework/ComparisonFailure

这指向真正的问题,现在只能找到哪个类依赖于JUnit。此类ArgumentsAreDifferent扩展junit.framework.ComparisonFailure,此异常出现在VerificationOverTimeImpl中的超时验证所需的try / catch块中。

这个问题可能是自1.10.x以来修复一些超时问题。

注意我也在mailing list上复制了这个答案。