diff --git a/src/main/java/org/mockito/Mockito.java b/src/main/java/org/mockito/Mockito.java index 428655e4a8..f6ad61d414 100644 --- a/src/main/java/org/mockito/Mockito.java +++ b/src/main/java/org/mockito/Mockito.java @@ -10,6 +10,7 @@ import org.mockito.internal.creation.MockSettingsImpl; import org.mockito.internal.framework.DefaultMockitoFramework; import org.mockito.internal.session.DefaultMockitoSessionBuilder; +import org.mockito.internal.util.MockUtil; import org.mockito.internal.verification.VerificationModeFactory; import org.mockito.invocation.Invocation; import org.mockito.invocation.InvocationFactory; @@ -2167,6 +2168,10 @@ public static T mock(Class classToMock, MockSettings mockSettings) { * @return a spy of the real object */ public static T spy(T object) { + if (MockUtil.isMock(object)) { + throw new IllegalArgumentException( + "Please don't pass mock here. Spy is not allowed on mock."); + } return MOCKITO_CORE.mock( (Class) object.getClass(), withSettings().spiedInstance(object).defaultAnswer(CALLS_REAL_METHODS)); diff --git a/src/test/java/org/mockitousage/constructor/CreatingMocksWithConstructorTest.java b/src/test/java/org/mockitousage/constructor/CreatingMocksWithConstructorTest.java index a70b5b25cc..10bb849461 100644 --- a/src/test/java/org/mockitousage/constructor/CreatingMocksWithConstructorTest.java +++ b/src/test/java/org/mockitousage/constructor/CreatingMocksWithConstructorTest.java @@ -409,6 +409,19 @@ public void handles_bridge_methods_correctly() { assertEquals("value", testBug.getValue(0)); } + + @Test + public void forbid_spy_on_mock() { + try { + spy(mock(List.class)); + fail(); + } catch (IllegalArgumentException e) { + assertThat(e) + .hasMessageContaining( + "Please don't pass mock here. Spy is not allowed on mock."); + } + } + public abstract class SomeAbstractClass { protected abstract String getRealValue(T value);