Search code examples
javatestngmockitojmock

java.lang.VerifyError with Mockito 1.10.17


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

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 issue happens in IntelliJ and with Maven. There is only 1 version of Mockito on the classpath. There is also JMock 2.5.1 on the classpath which I cannot remove since 99% of my unit tests still use JMock at this moment. I don't know if that has anything to do with it.

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

UPDATE 2:

This works:

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

And this does not:

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

UPDATE 3: I have made a small test project that has the exact same problem: See https://github.com/wimdeblauwe/mockito-verify-problem and run it from IntelliJ or with Maven.


Solution

  • The problem here is an unfortunate constellation between TestNG, JUnit and Mockto. To fix your issue, you just need to add a dependency to JUnit 4.0 or greater (the most recent version is currently 4.12):

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

    Here are the details:

    TestNG, which is apparently your testing framework, declares a dependency to the quite old JUnit version 3.8.1. Mockito does not declare a dependency to JUnit at all but it uses some JUnit classes that were introduced in JUnit 4.0 (!).

    Edit:

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

    From JUnit version 3.8.1 to 4.x the class hierarchy of ComparisonFailure changed to having AssertionError instead of Error as base class. The VerifiyError is caused because VerificationOverTimeImpl#handleVerifyException() requires an AssertionError but would be invoked with an Error when JUnit 3.8.1 is used.