Repository: mockito/mockito
Issue: VerifyError thrown when JUnit 3 is in the classpath
Labels: build

With JUnit 3 in the classpath, VerifyError will be thrown during JUnit detection in ExceptionFactory. This is because JUnit's ComparisonFailure class only starts extending AssertionError in JUnit 4.

**Expected Behavior**

When JUnit 3 is in the classpath, Mockito should behave as if JUnit was not there at all.

A real example where handling this here instead of updating JUnit in the consumer would be beneficial is related to my company's usage of ZooKeeper. ZooKeeper 3.4 leaks a JUnit 3.8.1 dependency that is fixed in 3.5, but 3.5 is still in beta and has been in the works for several years. Projects that use TestNG (most of ours) but which use ZooKeeper (usually transitively) run into this issue.

**Example**

src/test/java/com/example/ExampleTest.java
```
package com.example;

import org.testng.annotations.Test;
import static org.mockito.Mockito.*;

@Test
public class ExampleTest {
  public void testMockitoWithJUnit3() {
    Client mockClient = mock(Client.class);
    mockClient.call("one");
    verify(mockClient).call("two");
  }

  public interface Client {
    void call(String argument);
  }
}
```
build.gradle
```
plugins {
  id 'java'
  id 'idea'
}

repositories {
  mavenCentral()
}

dependencies {
  testImplementation group: 'junit', name: 'junit', version: '3.8.2'
  testImplementation group: 'org.mockito', name: 'mockito-core', version: '2.23.4'
  testImplementation group: 'org.testng', name: 'testng', version: '6.14.3'
}

test {
  useTestNG()
}
```

**Error**
```
java.lang.VerifyError: Bad return type
Exception Details:
  Location:
    org/mockito/internal/junit/ExceptionFactory$JUnitArgsAreDifferent.create(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/AssertionError; @10: areturn
  Reason:
    Type 'org/mockito/exceptions/verification/junit/ArgumentsAreDifferent' (current frame, stack[0]) is not assignable to 'java/lang/AssertionError' (from method signature)
  Current Frame:
    bci: @10
    flags: { }
    locals: { 'java/lang/String', 'java/lang/String', 'java/lang/String' }
    stack: { 'org/mockito/exceptions/verification/junit/ArgumentsAreDifferent' }
  Bytecode:
    0000000: bb00 0259 2a2b 2cb7 0003 b0            

	at org.mockito.internal.junit.ExceptionFactory.canLoadJunitClass(ExceptionFactory.java:33)
	at org.mockito.internal.junit.ExceptionFactory.<clinit>(ExceptionFactory.java:12)
	at org.mockito.internal.exceptions.Reporter.argumentsAreDifferent(Reporter.java:313)
        ...
```

Issue comments:

Pull request review comments:

Patch that resolved the issue:
diff --git a/src/main/java/org/mockito/internal/junit/ExceptionFactory.java b/src/main/java/org/mockito/internal/junit/ExceptionFactory.java
index 3664aea1a8..ee288d614a 100644
--- a/src/main/java/org/mockito/internal/junit/ExceptionFactory.java
+++ b/src/main/java/org/mockito/internal/junit/ExceptionFactory.java
@@ -31,7 +31,7 @@ private static AssertionError createJUnitArgumentsAreDifferent(String message, S
     private static boolean canLoadJunitClass() {
         try {
             JUnitArgsAreDifferent.create("message", "wanted", "actual");
-        } catch (NoClassDefFoundError onlyIfJUnitIsNotAvailable) {
+        } catch (Throwable onlyIfJUnitIsNotAvailable) {
             return false;
         }
         return true;


Test patch: