Java.lang.VerifyError using Mockito 1.10.17

I am trying to replace JMock with Mockito (1.10.17). I have already successfully passed some unit tests, but now I want to use the timeout function

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

and I get this exception:

 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) 

The problem occurs in IntelliJ and with Maven. There is only 1 version of Mockito on the way to classes. There is also JMock 2.5.1 on the class path, which I cannot remove, since 99% of my unit tests still use JMock at the moment. I do not know if this is related to this.

UPDATE: I tried with JMock 2.6.0 and Hamcrest 1.3, but the result is the same.

UPDATE 2:

It works:

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

And this is not so:

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

UPDATE 3: I did a small test project with the same problem: see https://github.com/wimdeblauwe/mockito-verify-problem and run it from IntelliJ or with Maven.

+5
source share
2 answers

The problem here is the failed constellation between TestNG, JUnit, and Mockto. To fix your problem, you just need to add a dependency on JUnit 4.0 or higher (the latest version is currently 4.12):

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

Here are the details:

TestNG, which seems to be your test environment, declares a dependency on a fairly old version of JNnit 3.8.1. Mockito does not declare a dependency on JUnit at all, but uses some of the JUnit classes that were introduced in JUnit 4.0 (!).

Edit:

The Mockito#timeout() method in your example creates an instance of Timeout , which in turn creates an instance of VerificationOverTimeImpl . The VerificationOverTimeImpl#verify() method handles an error of type ArgumentsAreDifferent , which is a subclass of org.junit.ComparisonFailure .

From JUnit version 3.8.1 - 4.x, the ComparisonFailure class hierarchy has changed to AssertionError instead of Error as the base class. VerifiyError caused because VerificationOverTimeImpl#handleVerifyException() requires an AssertionError , but will be VerificationOverTimeImpl#handleVerifyException() with Error when using JUnit 3.8.1.

+5
source

EDIT . At first glance, Stefan answered. Its diagnosis is almost correct, however org.mockito.exceptions.verification.junit.ArgumentsAreDifferent do extends junit.framework.ComparisonFailure , which is present in JUnit 3.x, and this is a TestNG 5.x dependency. VerifyError itself can do something when the JVM performs the binding, since there are changes to the ComparisonFailure type itself between JUnit 3.x and JUnit 4.x.

In any case, the problem in Mockito is that it uses the JUnit class, where it should not. And that Mockito no longer supports JUnit 3.x.

TL tr

We have a problem in the code inside of which the verification mode is used, using the JUnit class, which is not in the classpath. Adding JUnit depending on your POM will correct the situation.

Thanks for reporting. I created a problem on GitHub (# 152)

long story

For some reason, TestNG 5.xxx makes the JVM crash with VerifyError on a method that is not even called at this point.

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

But switching to the latest version of TestNG, 6.8. Somehow the JVM crashes with a clear reason: NoClassDefFoundError

 java.lang.NoClassDefFoundError: junit/framework/ComparisonFailure 

Which points to the real problem here, now only find which class depends on JUnit. This class ArgumentsAreDifferent , which extends junit.framework.ComparisonFailure , this exception appears in the try / catch block in VerificationOverTimeImpl , which is necessary for checking the timeout.

This problem probably exists from 1.10.x when fixing some timeout problems.

Note. I also copied this answer to the mailing list .

0
source

Source: https://habr.com/ru/post/1210178/


All Articles