Repository: mockito/mockito
Issue: thenThrow(Class) no longer creates new instances
Labels: please contribute

As of #1162, `thenThrow(Class)` no longer creates new instances for each invocation.  We had tests that were reliant on that behavior; for example:
```
	@Test
	public void thenThrow() {
		Supplier<Object> r = mock(Supplier.class);
		when(r.get()).thenThrow(RuntimeException.class);
		RuntimeException first = null;
		for (int i = 0; i < 2; i++) {
			try {
				r.get();
			} catch (RuntimeException e) {
				if (first == null) {
					first = e;
				} else {
					first.addSuppressed(e);
				}
			}
		}
		if (first != null) {
			throw first;
		}
	}
```
These tests now fail:
```
java.lang.IllegalArgumentException: Self-suppression not permitted
	at java.lang.Throwable.addSuppressed(Throwable.java:1043)
	at example.Test.thenThrow(Test.java:10)
```

Issue comments:
Hello, I've taken a look at the issue and it is still apparent in commit 560adf377677a4a2c658a0b24e2f9c2e0b373c20. It appears to be that `thenThrow(Class)` instantiates the Throwable when it is called rather than instantiating it upon mock interaction.

### Background
To why this leads to the behaviour described in the issue is that the Throwable is passed to `thenThrow(Throwable)` which instantiates a custom Answer with `new ThrowsException(throwable)` and passes into `thenAnswer(Answer)`. This Answer, of course, stores the Throwable and throws it with every repeat mock interaction.

Before the merge, `thenThrow(Class)` used to call `thenAnswer(Answer)` directly with its own custom Answer, ThrowsExceptionClass. This Answer instantiated the Exception with each mock interaction.

### Suggested Solution
My suggestion is to introduce an Answer similar to ThrowsExceptionClass described above (or a modified version of ThrowsException) and have `thenThrow(Class)` create that and call `thenAnswer(Answer)`.

I can think of two ways to implement the suggestion. Both ways involve storing the Class\<Throwable\> and using Objenesis to instantiate the Throwable in the new Answer class, however:

1. Create the new Answer class with similar code to ThrowsException but instead of throwing the stored Throwable it uses a new instance based of the stored Class\<Throwable\>.
2. Modify ThrowsException to use a protected getter method for the Throwable. Then extend ThrowsException with the new Answer for Class\<Throwable\> which overrides the getter method to instantiate a new Throwable.

Option 1 doesn't modify existing behaviour that works but has more duplicate code. Option 2 offers less duplicate code but modifies existing behaviour that works.

I prefer option 2.

Happy to review a PR for this. We probably need to make a few iterations on the design, but agreed we can fix this issue.

However, if the necessary changes appear to be complicated, I am inclined to close this as working as intended.

Pull request review comments:
Instead of `expected = `, use `assertThrows` and assert on the exception that it is of the correct exception class and it has the correct message.
Let's name this `ThrowsExceptionForClassType` to make it clear we are passing in the `.class` itself.
The change has been done. The class, references and associated variables have been updated.
I've replaced `expected = ` but I can't find the import for `assertThrows`. I think the tests are configured for JUnit 4 only and `assertThrows` was introduced in 5. If you have Jupiter configured in another test source then I can migrate it to there and do the necessary alterations.

For the current tests, I've used `Assertions.catchThrowable` and `Assertions.catchThrowableOfType` as an alternative.
Ah I misremembered the name. In AssertJ it is called `assertThatThrownBy`: https://joel-costigliola.github.io/assertj/assertj-core-features-highlight.html#exception-assertion

Patch that resolved the issue:
diff --git a/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java b/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java
index 73dab853d5..b3bd074428 100644
--- a/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java
+++ b/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java
@@ -7,11 +7,10 @@
 import static org.mockito.internal.exceptions.Reporter.notAnException;
 import static org.mockito.internal.progress.ThreadSafeMockingProgress.mockingProgress;
 
-import org.mockito.creation.instance.Instantiator;
-import org.mockito.internal.configuration.plugins.Plugins;
 import org.mockito.internal.stubbing.answers.CallsRealMethods;
 import org.mockito.internal.stubbing.answers.Returns;
 import org.mockito.internal.stubbing.answers.ThrowsException;
+import org.mockito.internal.stubbing.answers.ThrowsExceptionForClassType;
 import org.mockito.stubbing.Answer;
 import org.mockito.stubbing.OngoingStubbing;
 
@@ -75,8 +74,7 @@ public OngoingStubbing<T> thenThrow(Class<? extends Throwable> throwableType) {
             mockingProgress().reset();
             throw notAnException();
         }
-        Instantiator instantiator = Plugins.getInstantiatorProvider().getInstantiator(null);
-        return thenThrow(instantiator.newInstance(throwableType));
+        return thenAnswer(new ThrowsExceptionForClassType(throwableType));
     }
 
     @Override
diff --git a/src/main/java/org/mockito/internal/stubbing/StubberImpl.java b/src/main/java/org/mockito/internal/stubbing/StubberImpl.java
index d707cf8b3a..3f37af64b3 100644
--- a/src/main/java/org/mockito/internal/stubbing/StubberImpl.java
+++ b/src/main/java/org/mockito/internal/stubbing/StubberImpl.java
@@ -14,10 +14,10 @@
 import java.util.LinkedList;
 import java.util.List;
 
-import org.mockito.internal.configuration.plugins.Plugins;
 import org.mockito.internal.stubbing.answers.CallsRealMethods;
 import org.mockito.internal.stubbing.answers.Returns;
 import org.mockito.internal.stubbing.answers.ThrowsException;
+import org.mockito.internal.stubbing.answers.ThrowsExceptionForClassType;
 import org.mockito.internal.util.MockUtil;
 import org.mockito.quality.Strictness;
 import org.mockito.stubbing.Answer;
@@ -89,18 +89,7 @@ public Stubber doThrow(Class<? extends Throwable> toBeThrown) {
             mockingProgress().reset();
             throw notAnException();
         }
-        Throwable e = null;
-        try {
-            e = Plugins.getInstantiatorProvider().getInstantiator(null).newInstance(toBeThrown);
-        } finally {
-            if (e == null) {
-                //this means that an exception or error was thrown when trying to create new instance
-                //we don't want 'catch' statement here because we want the exception to be thrown to the user
-                //however, we do want to clean up state (e.g. "stubbing started").
-                mockingProgress().reset();
-            }
-        }
-        return doThrow(e);
+        return doAnswer(new ThrowsExceptionForClassType(toBeThrown));
     }
 
     @Override
diff --git a/src/main/java/org/mockito/internal/stubbing/answers/AbstractThrowsException.java b/src/main/java/org/mockito/internal/stubbing/answers/AbstractThrowsException.java
new file mode 100644
index 0000000000..47bf6d669b
--- /dev/null
+++ b/src/main/java/org/mockito/internal/stubbing/answers/AbstractThrowsException.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2020 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
+package org.mockito.internal.stubbing.answers;
+
+import static org.mockito.internal.exceptions.Reporter.cannotStubWithNullThrowable;
+import static org.mockito.internal.exceptions.Reporter.checkedExceptionInvalid;
+
+import org.mockito.internal.exceptions.stacktrace.ConditionalStackTraceFilter;
+import org.mockito.internal.util.MockUtil;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.mockito.stubbing.ValidableAnswer;
+
+public abstract class AbstractThrowsException implements Answer<Object>, ValidableAnswer {
+
+    private final ConditionalStackTraceFilter filter = new ConditionalStackTraceFilter();
+
+    protected abstract Throwable getThrowable();
+
+    public Object answer(InvocationOnMock invocation) throws Throwable {
+        Throwable throwable = getThrowable();
+        if (throwable == null) {
+            throw new IllegalStateException("throwable is null: " +
+                "you shall not call #answer if #validateFor fails!");
+        }
+        if (MockUtil.isMock(throwable)) {
+            throw throwable;
+        }
+        Throwable t = throwable.fillInStackTrace();
+
+        if (t == null) {
+            //Custom exceptions sometimes return null, see #866
+            throw throwable;
+        }
+        filter.filter(t);
+        throw t;
+    }
+
+    @Override
+    public void validateFor(InvocationOnMock invocation) {
+        Throwable throwable = getThrowable();
+        if (throwable == null) {
+            throw cannotStubWithNullThrowable();
+        }
+
+        if (throwable instanceof RuntimeException || throwable instanceof Error) {
+            return;
+        }
+
+        if (!new InvocationInfo(invocation).isValidException(throwable)) {
+            throw checkedExceptionInvalid(throwable);
+        }
+    }
+}
diff --git a/src/main/java/org/mockito/internal/stubbing/answers/ThrowsException.java b/src/main/java/org/mockito/internal/stubbing/answers/ThrowsException.java
index bc1b987f37..1250a88882 100644
--- a/src/main/java/org/mockito/internal/stubbing/answers/ThrowsException.java
+++ b/src/main/java/org/mockito/internal/stubbing/answers/ThrowsException.java
@@ -4,25 +4,19 @@
  */
 package org.mockito.internal.stubbing.answers;
 
-import static org.mockito.internal.exceptions.Reporter.cannotStubWithNullThrowable;
-import static org.mockito.internal.exceptions.Reporter.checkedExceptionInvalid;
 
 import java.io.Serializable;
 
-import org.mockito.internal.exceptions.stacktrace.ConditionalStackTraceFilter;
-import org.mockito.internal.util.MockUtil;
 import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
 import org.mockito.stubbing.ValidableAnswer;
 
 /**
  * An answer that always throws the same throwable.
  */
-public class ThrowsException implements Answer<Object>, ValidableAnswer, Serializable {
+public class ThrowsException extends AbstractThrowsException implements Serializable {
 
     private static final long serialVersionUID = 1128820328555183980L;
     private final Throwable throwable;
-    private final ConditionalStackTraceFilter filter = new ConditionalStackTraceFilter();
 
     /**
      * Creates a new answer always throwing the given throwable. If it is null,
@@ -33,36 +27,9 @@ public ThrowsException(Throwable throwable) {
         this.throwable = throwable;
     }
 
-    public Object answer(InvocationOnMock invocation) throws Throwable {
-        if (throwable == null) {
-            throw new IllegalStateException("throwable is null: " +
-                "you shall not call #answer if #validateFor fails!");
-        }
-        if (MockUtil.isMock(throwable)) {
-            throw throwable;
-        }
-        Throwable t = throwable.fillInStackTrace();
-
-        if (t == null) {
-            //Custom exceptions sometimes return null, see #866
-            throw throwable;
-        }
-        filter.filter(t);
-        throw t;
-    }
-
     @Override
-    public void validateFor(InvocationOnMock invocation) {
-        if (throwable == null) {
-            throw cannotStubWithNullThrowable();
-        }
-
-        if (throwable instanceof RuntimeException || throwable instanceof Error) {
-            return;
-        }
-
-        if (!new InvocationInfo(invocation).isValidException(throwable)) {
-            throw checkedExceptionInvalid(throwable);
-        }
+    protected Throwable getThrowable() {
+        return throwable;
     }
+
 }
diff --git a/src/main/java/org/mockito/internal/stubbing/answers/ThrowsExceptionForClassType.java b/src/main/java/org/mockito/internal/stubbing/answers/ThrowsExceptionForClassType.java
new file mode 100644
index 0000000000..2c3d923956
--- /dev/null
+++ b/src/main/java/org/mockito/internal/stubbing/answers/ThrowsExceptionForClassType.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2020 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
+package org.mockito.internal.stubbing.answers;
+
+import java.io.Serializable;
+
+import org.mockito.creation.instance.Instantiator;
+import org.mockito.internal.configuration.plugins.Plugins;
+
+public class ThrowsExceptionForClassType extends AbstractThrowsException implements Serializable {
+
+    private final Class<? extends Throwable> throwableClass;
+
+    public ThrowsExceptionForClassType(Class<? extends Throwable> throwableClass) {
+        this.throwableClass = throwableClass;
+    }
+
+    @Override
+    protected Throwable getThrowable() {
+        Instantiator instantiator = Plugins.getInstantiatorProvider().getInstantiator(null);
+        return instantiator.newInstance(throwableClass);
+    }
+}


Test patch:
diff --git a/src/test/java/org/mockito/internal/stubbing/answers/AbstractThrowsExceptionTest.java b/src/test/java/org/mockito/internal/stubbing/answers/AbstractThrowsExceptionTest.java
new file mode 100644
index 0000000000..8fa4d86f58
--- /dev/null
+++ b/src/test/java/org/mockito/internal/stubbing/answers/AbstractThrowsExceptionTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2020 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
+package org.mockito.internal.stubbing.answers;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.mockito.Mockito.mock;
+import static org.mockito.internal.exceptions.Reporter.cannotStubWithNullThrowable;
+import static org.mockito.internal.exceptions.Reporter.checkedExceptionInvalid;
+
+import java.io.IOException;
+import java.nio.charset.CharacterCodingException;
+
+import org.assertj.core.api.Assertions;
+import org.junit.Test;
+import org.mockito.exceptions.base.MockitoException;
+import org.mockito.internal.invocation.InvocationBuilder;
+import org.mockito.invocation.Invocation;
+
+public class AbstractThrowsExceptionTest {
+
+    @Test
+    public void should_raise_wanted_throwable() {
+        Throwable expected = new Exception();
+        AbstractThrowsException ate = instantiateFixture(expected);
+
+        Throwable throwable = Assertions.catchThrowable(() -> ate.answer(createMethodInvocation()));
+        assertNotNull("Should have raised an exception.", throwable);
+        assertSame(expected, throwable);
+    }
+
+    @Test
+    public void should_throw_mock_exception_without_stacktrace() {
+        AbstractThrowsException ate = instantiateFixture(mock(Exception.class));
+
+        Throwable throwable = Assertions.catchThrowable(() -> ate.answer(createMethodInvocation()));
+        assertNotNull("Should have raised an exception.", throwable);
+        assertThat(throwable.getStackTrace()).describedAs("no stack trace, it's mock").isNull();
+    }
+
+    @Test
+    public void should_fill_in_exception_stacktrace() {
+        AbstractThrowsException ate = instantiateFixture(new Exception());
+
+        Throwable throwable = Assertions.catchThrowable(() -> ate.answer(createMethodInvocation()));
+        assertNotNull("Should have raised an exception.", throwable);
+        assertThat(throwable.getStackTrace()[0].getClassName()).isEqualTo(AbstractThrowsException.class.getName());
+        assertThat(throwable.getStackTrace()[0].getMethodName()).isEqualTo("answer");
+    }
+
+    @Test
+    public void should_invalidate_null_throwable() {
+        AbstractThrowsException ate = instantiateFixture(null);
+
+        Throwable throwable = Assertions.catchThrowableOfType(() -> ate.validateFor(createMethodInvocation()),
+                                                              MockitoException.class);
+        assertNotNull("Should have raised a MockitoException.", throwable);
+        assertEquals(cannotStubWithNullThrowable().getMessage(), throwable.getMessage());
+    }
+
+    @Test
+    public void should_throw_illegal_state_exception_if_null_answer() {
+        AbstractThrowsException ate = instantiateFixture(null);
+
+        Throwable throwable = Assertions.catchThrowableOfType(() -> ate.answer(createMethodInvocation()),
+                                                              IllegalStateException.class);
+        assertNotNull("Should have raised a IllegalStateException.", throwable);
+        assertEquals("throwable is null: you shall not call #answer if #validateFor fails!", throwable.getMessage());
+    }
+
+    @Test
+    public void should_pass_proper_checked_exception() {
+        instantiateFixture(new CharacterCodingException()).validateFor(createMethodInvocation());
+    }
+
+    @Test
+    public void should_fail_invalid_checked_exception() {
+        AbstractThrowsException ate = instantiateFixture(new IOException());
+        Throwable comparison = ate.getThrowable();
+
+        Throwable throwable = Assertions.catchThrowableOfType(() -> ate.validateFor(createMethodInvocation()),
+                                                              MockitoException.class);
+        assertNotNull("Should have raised a MockitoException.", throwable);
+        assertEquals(checkedExceptionInvalid(comparison).getMessage(), throwable.getMessage());
+    }
+
+    @Test
+    public void should_pass_RuntimeException() {
+        instantiateFixture(new RuntimeException()).validateFor(createMethodInvocation());
+    }
+
+    @Test
+    public void should_pass_Error() {
+        instantiateFixture(new Error()).validateFor(createMethodInvocation());
+    }
+
+    /** Creates a fixture for AbstractThrowsException that returns the given Throwable. */
+    private static AbstractThrowsException instantiateFixture(Throwable throwable) {
+        return new AbstractThrowsException() {
+            @Override
+            protected Throwable getThrowable() {
+                return throwable;
+            }
+        };
+    }
+
+    /** Creates Invocation of a "canThrowException" method call. */
+    private static Invocation createMethodInvocation() {
+        return new InvocationBuilder()
+            .method("canThrowException")
+            .toInvocation();
+    }
+
+    @Test
+    public void fixture_should_return_expected_throwable() {
+        Throwable expected = new RuntimeException();
+        AbstractThrowsException ate = instantiateFixture(expected);
+
+        assertSame(expected, ate.getThrowable());
+    }
+}
diff --git a/src/test/java/org/mockito/internal/stubbing/answers/ThrowsExceptionForClassTypeTest.java b/src/test/java/org/mockito/internal/stubbing/answers/ThrowsExceptionForClassTypeTest.java
new file mode 100644
index 0000000000..9aa67d098a
--- /dev/null
+++ b/src/test/java/org/mockito/internal/stubbing/answers/ThrowsExceptionForClassTypeTest.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2020 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
+package org.mockito.internal.stubbing.answers;
+
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+
+import org.junit.Test;
+
+public class ThrowsExceptionForClassTypeTest {
+    @Test
+    public void should_return_throwable_of_expected_class() {
+        ThrowsExceptionForClassType throwsExceptionForClassType = new ThrowsExceptionForClassType(Exception.class);
+
+        assertSame(Exception.class, throwsExceptionForClassType.getThrowable().getClass());
+    }
+
+    @Test
+    public void should_return_different_throwables() {
+        ThrowsExceptionForClassType throwsExceptionForClassType = new ThrowsExceptionForClassType(Exception.class);
+
+        Throwable first = throwsExceptionForClassType.getThrowable();
+        Throwable second = throwsExceptionForClassType.getThrowable();
+        assertNotSame(first, second);
+    }
+}
diff --git a/src/test/java/org/mockito/internal/stubbing/answers/ThrowsExceptionTest.java b/src/test/java/org/mockito/internal/stubbing/answers/ThrowsExceptionTest.java
index 6940244997..2da1e04596 100644
--- a/src/test/java/org/mockito/internal/stubbing/answers/ThrowsExceptionTest.java
+++ b/src/test/java/org/mockito/internal/stubbing/answers/ThrowsExceptionTest.java
@@ -6,6 +6,7 @@
 
 import static junit.framework.TestCase.fail;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertSame;
 import static org.mockito.Mockito.mock;
 
 import java.io.IOException;
@@ -54,7 +55,7 @@ public void should_fill_in_exception_stacktrace() throws Exception {
         } catch (Throwable throwable) {
             // then
             throwable.printStackTrace();
-            assertThat(throwableToRaise.getStackTrace()[0].getClassName()).isEqualTo(ThrowsException.class.getName());
+            assertThat(throwableToRaise.getStackTrace()[0].getClassName()).isEqualTo(AbstractThrowsException.class.getName());
             assertThat(throwableToRaise.getStackTrace()[0].getMethodName()).isEqualTo("answer");
         }
     }
@@ -94,6 +95,23 @@ public void should_pass_RuntimeExceptions() throws Throwable {
         new ThrowsException(new RuntimeException()).validateFor(createMethodInvocation());
     }
 
+    @Test
+    public void should_return_expected_throwable() {
+        Throwable expected = new Exception();
+        ThrowsException throwsException = new ThrowsException(expected);
+
+        assertSame(expected, throwsException.getThrowable());
+    }
+
+    @Test
+    public void should_return_same_throwable() {
+        ThrowsException throwsException = new ThrowsException(new Exception());
+
+        Throwable first = throwsException.getThrowable();
+        Throwable second = throwsException.getThrowable();
+        assertSame(first, second);
+    }
+
     /** Creates Invocation of a "canThrowException" method call. */
     private static Invocation createMethodInvocation() {
         return new InvocationBuilder()
diff --git a/src/test/java/org/mockitousage/stubbing/StubbingWithThrowablesTest.java b/src/test/java/org/mockitousage/stubbing/StubbingWithThrowablesTest.java
index 3798ca735f..3b93f3c7db 100644
--- a/src/test/java/org/mockitousage/stubbing/StubbingWithThrowablesTest.java
+++ b/src/test/java/org/mockitousage/stubbing/StubbingWithThrowablesTest.java
@@ -6,6 +6,7 @@
 
 import static org.hamcrest.CoreMatchers.sameInstance;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -92,6 +93,30 @@ public void call() {
         }).isInstanceOf(ExceptionOne.class);
     }
 
+    @Test
+    public void throws_new_exception_consecutively_from_class() {
+        when(mock.add(null)).thenThrow(NaughtyException.class);
+
+        NaughtyException first =  Assertions.catchThrowableOfType(() -> mock.add(null),
+                                                                  NaughtyException.class);
+        NaughtyException second = Assertions.catchThrowableOfType(() -> mock.add(null),
+                                                                  NaughtyException.class);
+
+        assertNotSame(first, second);
+    }
+
+    @Test
+    public void throws_new_exception_consecutively_from_class_with_doThrow() {
+        doThrow(NaughtyException.class).when(mock).add(null);
+
+        NaughtyException first =  Assertions.catchThrowableOfType(() -> mock.add(null),
+                                                                  NaughtyException.class);
+        NaughtyException second = Assertions.catchThrowableOfType(() -> mock.add(null),
+                                                                  NaughtyException.class);
+
+        assertNotSame(first, second);
+    }
+
     @Test
     public void shouldStubWithThrowable() throws Exception {
         IllegalArgumentException expected = new IllegalArgumentException("thrown by mock");
diff --git a/subprojects/junit-jupiter/src/test/java/org/mockitousage/UninstantiableThrowableTest.java b/subprojects/junit-jupiter/src/test/java/org/mockitousage/UninstantiableThrowableTest.java
deleted file mode 100644
index 2ef3128016..0000000000
--- a/subprojects/junit-jupiter/src/test/java/org/mockitousage/UninstantiableThrowableTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2018 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockitousage;
-
-import org.assertj.core.api.Assertions;
-import org.junit.jupiter.api.RepeatedTest;
-import org.junit.jupiter.api.RepetitionInfo;
-import org.mockito.Mockito;
-
-import java.util.List;
-
-//issue 1514
-class UninstantiableThrowableTest {
-
-    @RepeatedTest(2)
-    void should_behave_consistently(RepetitionInfo i) {
-        List mock = Mockito.mock(List.class);
-        if (i.getCurrentRepetition() == 1) {
-            Assertions.assertThatThrownBy(
-                () -> Mockito.doThrow(UninstantiableException.class).when(mock).clear())
-                .isInstanceOf(InstantiationError.class);
-        }
-
-        // The following operation results in "UnfinishedStubbing"
-        Mockito.doThrow(RuntimeException.class).when(mock).clear();
-    }
-
-    abstract static class UninstantiableException extends RuntimeException { }
-}