Repository: mockito/mockito
Issue: Misleading behavior of Mockito.verifyZeroInteractions()
Labels: 2.* incompatible
feedback-needed

## Problem

Mockito.verifyZeroInteractions() actually does not do what it advertises. The purpose of this ticket is to discuss whether to change the behavior of this method in Mockito 3.

## Details

Based on user feedback at #977, from @ffissore, "verifyZeroInteractions" API can be misleading. When you read that method in test code, you expect zero interactions with specified mocks. However, "verifyZeroInteractions" is only an alias to "verifyNoMoreInteractions" and in fact, it **does not** guarantee that there were zero interactions. Let's use examples to illustrate the problem

## Feedback needed

Please comment / vote / state your opinion about changing the behavior of "verifyZeroInteractions" so that it actually ensures that there were **zero** interactions with the mock (regardless if previously verified or not).

## Examples

Below examples illustrate current behavior of Mockito 2.x, in case you are puzzled what this ticket is about.

Example 1 - verifyNoMoreInteractions

```java
mock.foo();
verify(mock).foo();
verifyNoMoreInteractions(mock); //pretty clear I think
```

Example 2 - verifyZeroInteractions

```java
mock.foo();
verify(mock).foo();

verifyZeroInteractions(mock);
//above passes because verifyZeroInteractions == verifyNoMoreInteractions
//and we already have verified the only method invoked on the mock
```

Example 3 - verifyZeroInteractions with regular stubbing

```java
given(mock.foo()).willReturn("x");
assertEquals("x", mock.foo());
verify(mock).foo();

verifyZeroInteractions(mock);
//above passes because verifyZeroInteractions == verifyNoMoreInteractions
```

Example 4 - verifyZeroInteractions with new strict stubbing

```java
given(mock.foo()).willReturn("x");
assertEquals("x", mock.foo());

verifyZeroInteractions(mock);
//above passes because with strict stubbing
//stubbed method are implicitly verified when they are "used"
//this is one of key features of strict stubbing (DRY, don't repeat yourself)
```

Issue comments:
This was fixed in #989

Pull request review comments:
Let's add a `@deprecated since 3.0.0` here, so we don't accidently remove it in the wrong version (which we did previously)
Since we deprecate the method anyways, is this test really required?
This still needs a `@since`
I would rather not name it with `2`. Probably better as `should_remove_all_interactions_verify_no_interactions()`
Same here
Same here
Same here
Same here
Same here
Same here
@ffissore We should avoid this catch block by calling `MockUtil.isMock(..)`

Patch that resolved the issue:
diff --git a/src/main/java/org/mockito/BDDMockito.java b/src/main/java/org/mockito/BDDMockito.java
index 9090fa891d..ef478a1082 100644
--- a/src/main/java/org/mockito/BDDMockito.java
+++ b/src/main/java/org/mockito/BDDMockito.java
@@ -259,6 +259,12 @@ public interface Then<T> {
          * @since 2.1.0
          */
         void shouldHaveNoMoreInteractions();
+
+        /**
+         * @see #verifyNoInteractions(Object...)
+         * @since 3.0.0
+         */
+        void shouldHaveNoInteractions();
     }
 
     private static class ThenImpl<T> implements Then<T> {
@@ -304,11 +310,21 @@ public T should(InOrder inOrder, VerificationMode mode) {
         /**
          * @see #verifyZeroInteractions(Object...)
          * @since 2.1.0
+         * @deprecated Since 3.0.0. Please migrate your code to {@link #shouldHaveNoInteractions()}
          */
+        @Deprecated
         public void shouldHaveZeroInteractions() {
             verifyZeroInteractions(mock);
         }
 
+        /**
+         * @see #verifyNoInteractions(Object...)
+         * @since 3.0.0
+         */
+        public void shouldHaveNoInteractions() {
+            verifyNoInteractions(mock);
+        }
+
         /**
          * @see #verifyNoMoreInteractions(Object...)
          * @since 2.1.0
diff --git a/src/main/java/org/mockito/Mockito.java b/src/main/java/org/mockito/Mockito.java
index 73ff1f2583..c469ac0f1f 100644
--- a/src/main/java/org/mockito/Mockito.java
+++ b/src/main/java/org/mockito/Mockito.java
@@ -2010,11 +2010,33 @@ public static void verifyNoMoreInteractions(Object... mocks) {
      * See examples in javadoc for {@link Mockito} class
      *
      * @param mocks to be verified
+     * @deprecated Since 3.0.0. Please migrate your code to {@link #verifyNoInteractions(Object...)}
      */
+    @Deprecated
     public static void verifyZeroInteractions(Object... mocks) {
         MOCKITO_CORE.verifyNoMoreInteractions(mocks);
     }
 
+    /**
+     * Verifies that no interactions happened on given mocks.
+     * <pre class="code"><code class="java">
+     *   verifyNoInteractions(mockOne, mockTwo);
+     * </code></pre>
+     * This method will also detect invocations
+     * that occurred before the test method, for example: in <code>setUp()</code>, <code>&#064;Before</code> method or in constructor.
+     * Consider writing nice code that makes interactions only in test methods.
+     * <p>
+     * See also {@link Mockito#never()} - it is more explicit and communicates the intent well.
+     * <p>
+     * See examples in javadoc for {@link Mockito} class
+     *
+     * @since 3.0.0
+     * @param mocks to be verified
+     */
+    public static void verifyNoInteractions(Object... mocks) {
+        MOCKITO_CORE.verifyNoInteractions(mocks);
+    }
+
     /**
      * Use <code>doThrow()</code> when you want to stub the void method with an exception.
      * <p>
diff --git a/src/main/java/org/mockito/internal/MockitoCore.java b/src/main/java/org/mockito/internal/MockitoCore.java
index 791e0d1d64..ba93131f46 100644
--- a/src/main/java/org/mockito/internal/MockitoCore.java
+++ b/src/main/java/org/mockito/internal/MockitoCore.java
@@ -19,6 +19,7 @@
 import static org.mockito.internal.util.MockUtil.isMock;
 import static org.mockito.internal.util.MockUtil.resetMock;
 import static org.mockito.internal.util.MockUtil.typeMockabilityOf;
+import static org.mockito.internal.verification.VerificationModeFactory.noInteractions;
 import static org.mockito.internal.verification.VerificationModeFactory.noMoreInteractions;
 
 import java.util.Arrays;
@@ -137,6 +138,28 @@ public void verifyNoMoreInteractionsInOrder(List<Object> mocks, InOrderContext i
         VerificationModeFactory.noMoreInteractions().verifyInOrder(data);
     }
 
+    /**
+     * Verifies that given mocks have been invoked zero times, failing otherwise
+     *
+     * @since 3.0.0
+     * @param mocks the mocks to verify
+     */
+    public void verifyNoInteractions(Object... mocks) {
+        assertMocksNotEmpty(mocks);
+        mockingProgress().validateState();
+        for (Object mock : mocks) {
+            if (mock == null) {
+                throw nullPassedToVerifyNoMoreInteractions();
+            }
+            if (!isMock(mock)) {
+                throw notAMockPassedToVerifyNoMoreInteractions();
+            }
+            InvocationContainer invocations = getMockHandler(mock).getInvocationContainer();
+            VerificationDataImpl data = new VerificationDataImpl(invocations, null);
+            noInteractions().verify(data);
+        }
+    }
+
     private void assertMocksNotEmpty(Object[] mocks) {
         if (mocks == null || mocks.length == 0) {
             throw mocksHaveToBePassedToVerifyNoMoreInteractions();
diff --git a/src/main/java/org/mockito/internal/exceptions/Reporter.java b/src/main/java/org/mockito/internal/exceptions/Reporter.java
index 7544557047..05db983691 100644
--- a/src/main/java/org/mockito/internal/exceptions/Reporter.java
+++ b/src/main/java/org/mockito/internal/exceptions/Reporter.java
@@ -185,7 +185,7 @@ public static MockitoException mocksHaveToBePassedToVerifyNoMoreInteractions() {
                 "Method requires argument(s)!",
                 "Pass mocks that should be verified, e.g:",
                 "    verifyNoMoreInteractions(mockOne, mockTwo);",
-                "    verifyZeroInteractions(mockOne, mockTwo);",
+                "    verifyNoInteractions(mockOne, mockTwo);",
                 ""
         ));
     }
@@ -195,7 +195,7 @@ public static MockitoException notAMockPassedToVerifyNoMoreInteractions() {
                 "Argument(s) passed is not a mock!",
                 "Examples of correct verifications:",
                 "    verifyNoMoreInteractions(mockOne, mockTwo);",
-                "    verifyZeroInteractions(mockOne, mockTwo);",
+                "    verifyNoInteractions(mockOne, mockTwo);",
                 ""
         ));
     }
@@ -205,7 +205,7 @@ public static MockitoException nullPassedToVerifyNoMoreInteractions() {
                 "Argument(s) passed is null!",
                 "Examples of correct verifications:",
                 "    verifyNoMoreInteractions(mockOne, mockTwo);",
-                "    verifyZeroInteractions(mockOne, mockTwo);"
+                "    verifyNoInteractions(mockOne, mockTwo);"
         ));
     }
 
@@ -443,6 +443,23 @@ public static MockitoAssertionError noMoreInteractionsWanted(Invocation undesire
         ));
     }
 
+    public static MockitoAssertionError noInteractionsWanted(Object mock, List<VerificationAwareInvocation> invocations) {
+        ScenarioPrinter scenarioPrinter = new ScenarioPrinter();
+        String scenario = scenarioPrinter.print(invocations);
+
+        List<Location> locations = new ArrayList<Location>();
+        for (VerificationAwareInvocation invocation : invocations) {
+            locations.add(invocation.getLocation());
+        }
+        return new NoInteractionsWanted(join(
+            "No interactions wanted here:",
+            new LocationImpl(),
+            "But found these interactions on mock '" + safelyGetMockName(mock) + "':",
+            join("", locations),
+            scenario
+        ));
+    }
+
     public static MockitoAssertionError noMoreInteractionsWantedInOrder(Invocation undesired) {
         return new VerificationInOrderFailure(join(
                 "No interactions wanted here:",
diff --git a/src/main/java/org/mockito/internal/verification/NoInteractions.java b/src/main/java/org/mockito/internal/verification/NoInteractions.java
new file mode 100644
index 0000000000..854a77c46d
--- /dev/null
+++ b/src/main/java/org/mockito/internal/verification/NoInteractions.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
+
+package org.mockito.internal.verification;
+
+import java.util.List;
+
+import org.mockito.internal.verification.api.VerificationData;
+import org.mockito.invocation.Invocation;
+import org.mockito.verification.VerificationMode;
+
+import static org.mockito.internal.exceptions.Reporter.noInteractionsWanted;
+
+public class NoInteractions implements VerificationMode {
+
+    @SuppressWarnings("unchecked")
+    public void verify(VerificationData data) {
+        List<Invocation> invocations = data.getAllInvocations();
+        if (!invocations.isEmpty()) {
+            throw noInteractionsWanted(invocations.get(0).getMock(), (List) invocations);
+        }
+    }
+
+    @Override
+    public VerificationMode description(String description) {
+        return VerificationModeFactory.description(this, description);
+    }
+}
diff --git a/src/main/java/org/mockito/internal/verification/VerificationModeFactory.java b/src/main/java/org/mockito/internal/verification/VerificationModeFactory.java
index 1f8e8b6c25..9ba2499fbf 100644
--- a/src/main/java/org/mockito/internal/verification/VerificationModeFactory.java
+++ b/src/main/java/org/mockito/internal/verification/VerificationModeFactory.java
@@ -33,6 +33,10 @@ public static NoMoreInteractions noMoreInteractions() {
         return new NoMoreInteractions();
     }
 
+    public static NoInteractions noInteractions() {
+        return new NoInteractions();
+    }
+
     public static VerificationMode atMost(int maxNumberOfInvocations) {
         return new AtMost(maxNumberOfInvocations);
     }


Test patch:
diff --git a/src/test/java/org/mockito/MockitoTest.java b/src/test/java/org/mockito/MockitoTest.java
index 3b96aff3b0..c25be8d28f 100644
--- a/src/test/java/org/mockito/MockitoTest.java
+++ b/src/test/java/org/mockito/MockitoTest.java
@@ -12,6 +12,7 @@
 import java.util.List;
 import org.junit.Test;
 import org.mockito.exceptions.misusing.NotAMockException;
+import org.mockito.exceptions.misusing.NullInsteadOfMockException;
 import org.mockito.internal.creation.MockSettingsImpl;
 
 @SuppressWarnings("unchecked")
@@ -45,6 +46,16 @@ public void shouldValidateMockWhenVerifyingZeroInteractions() {
         Mockito.verifyZeroInteractions("notMock");
     }
 
+    @Test(expected=NotAMockException.class)
+    public void shouldValidateMockWhenVerifyingNoInteractions() {
+        Mockito.verifyNoInteractions("notMock");
+    }
+
+    @Test(expected=NullInsteadOfMockException.class)
+    public void shouldValidateNullMockWhenVerifyingNoInteractions() {
+        Mockito.verifyNoInteractions(new Object[] { null });
+    }
+
     @Test(expected=NotAMockException.class)
     public void shouldValidateMockWhenCreatingInOrderObject() {
         Mockito.inOrder("notMock");
diff --git a/src/test/java/org/mockito/internal/InvalidStateDetectionTest.java b/src/test/java/org/mockito/internal/InvalidStateDetectionTest.java
index 850b9490d6..d326409b3f 100644
--- a/src/test/java/org/mockito/internal/InvalidStateDetectionTest.java
+++ b/src/test/java/org/mockito/internal/InvalidStateDetectionTest.java
@@ -63,6 +63,9 @@ public void shouldDetectUnfinishedStubbing() {
         when(mock.simpleMethod());
         detectsAndCleansUp(new OnVerifyZeroInteractions(), UnfinishedStubbingException.class);
 
+        when(mock.simpleMethod());
+        detectsAndCleansUp(new OnVerifyNoInteractions(), UnfinishedStubbingException.class);
+
         when(mock.simpleMethod());
         detectsAndCleansUp(new OnVerifyNoMoreInteractions(), UnfinishedStubbingException.class);
 
@@ -87,6 +90,9 @@ public void shouldDetectUnfinishedDoAnswerStubbing() {
         doAnswer(null);
         detectsAndCleansUp(new OnVerifyZeroInteractions(), UnfinishedStubbingException.class);
 
+        doAnswer(null);
+        detectsAndCleansUp(new OnVerifyNoInteractions(), UnfinishedStubbingException.class);
+
         doAnswer(null);
         detectsAndCleansUp(new OnVerifyNoMoreInteractions(), UnfinishedStubbingException.class);
 
@@ -108,6 +114,9 @@ public void shouldDetectUnfinishedVerification() {
         verify(mock);
         detectsAndCleansUp(new OnVerifyZeroInteractions(), UnfinishedVerificationException.class);
 
+        verify(mock);
+        detectsAndCleansUp(new OnVerifyNoInteractions(), UnfinishedVerificationException.class);
+
         verify(mock);
         detectsAndCleansUp(new OnVerifyNoMoreInteractions(), UnfinishedVerificationException.class);
 
@@ -126,6 +135,9 @@ public void shouldDetectMisplacedArgumentMatcher() {
         anyObject();
         detectsAndCleansUp(new OnVerifyZeroInteractions(), InvalidUseOfMatchersException.class);
 
+        anyObject();
+        detectsAndCleansUp(new OnVerifyNoInteractions(), InvalidUseOfMatchersException.class);
+
         anyObject();
         detectsAndCleansUp(new OnVerifyNoMoreInteractions(), InvalidUseOfMatchersException.class);
 
@@ -184,6 +196,12 @@ public void detect(IMethods mock) {
         }
     }
 
+    private static class OnVerifyNoInteractions implements DetectsInvalidState {
+        public void detect(IMethods mock) {
+            verifyNoInteractions(mock);
+        }
+    }
+
     private static class OnVerifyNoMoreInteractions implements DetectsInvalidState {
         public void detect(IMethods mock) {
             verifyNoMoreInteractions(mock);
diff --git a/src/test/java/org/mockito/internal/verification/NoInteractionsTest.java b/src/test/java/org/mockito/internal/verification/NoInteractionsTest.java
new file mode 100644
index 0000000000..9d268d7156
--- /dev/null
+++ b/src/test/java/org/mockito/internal/verification/NoInteractionsTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
+package org.mockito.internal.verification;
+
+import org.assertj.core.api.Assertions;
+import org.junit.Test;
+import org.mockito.exceptions.verification.NoInteractionsWanted;
+import org.mockito.internal.creation.MockSettingsImpl;
+import org.mockito.internal.invocation.InvocationBuilder;
+import org.mockito.internal.invocation.InvocationMatcher;
+import org.mockito.internal.stubbing.InvocationContainerImpl;
+import org.mockitousage.IMethods;
+import org.mockitoutil.TestBase;
+
+import static junit.framework.TestCase.*;
+import static org.mockito.Mockito.mock;
+
+public class NoInteractionsTest extends TestBase {
+
+    @Test
+    public void noInteractionsExceptionMessageShouldDescribeMock() {
+        //given
+        NoInteractions n = new NoInteractions();
+        IMethods mock = mock(IMethods.class, "a mock");
+        InvocationMatcher i = new InvocationBuilder().mock(mock).toInvocationMatcher();
+
+        InvocationContainerImpl invocations =
+            new InvocationContainerImpl( new MockSettingsImpl());
+        invocations.setInvocationForPotentialStubbing(i);
+
+        try {
+            //when
+            n.verify(new VerificationDataImpl(invocations, null));
+            //then
+            fail();
+        } catch (NoInteractionsWanted e) {
+            Assertions.assertThat(e.toString()).contains(mock.toString());
+        }
+    }
+
+}
diff --git a/src/test/java/org/mockitousage/basicapi/ResetTest.java b/src/test/java/org/mockitousage/basicapi/ResetTest.java
index 5ec69cc64f..09f893e9ec 100644
--- a/src/test/java/org/mockitousage/basicapi/ResetTest.java
+++ b/src/test/java/org/mockitousage/basicapi/ResetTest.java
@@ -62,6 +62,13 @@ public void shouldRemoveAllInteractions() throws Exception {
         verifyZeroInteractions(mock);
     }
 
+    @Test
+    public void shouldRemoveAllInteractionsVerifyNoInteractions() throws Exception {
+        mock.simpleMethod(1);
+        reset(mock);
+        verifyNoInteractions(mock);
+    }
+
     @Test
     public void shouldRemoveStubbingToString() throws Exception {
         IMethods mockTwo = mock(IMethods.class);
@@ -78,6 +85,14 @@ public void shouldStubbingNotBeTreatedAsInteraction() {
         verifyZeroInteractions(mock);
     }
 
+    @Test
+    public void shouldStubbingNotBeTreatedAsInteractionVerifyNoInteractions() {
+        when(mock.simpleMethod("one")).thenThrow(new RuntimeException());
+        doThrow(new RuntimeException()).when(mock).simpleMethod("two");
+        reset(mock);
+        verifyNoInteractions(mock);
+    }
+
     @Test
     public void shouldNotAffectMockName() {
         IMethods mock = mock(IMethods.class, "mockie");
diff --git a/src/test/java/org/mockitousage/customization/BDDMockitoTest.java b/src/test/java/org/mockitousage/customization/BDDMockitoTest.java
index 6830765b23..bc3bfb6cbb 100644
--- a/src/test/java/org/mockitousage/customization/BDDMockitoTest.java
+++ b/src/test/java/org/mockitousage/customization/BDDMockitoTest.java
@@ -268,6 +268,11 @@ public void should_validate_that_mock_did_not_have_any_interactions() {
         then(mock).shouldHaveZeroInteractions();
     }
 
+    @Test
+    public void should_validate_that_mock_had_no_interactions() {
+        then(mock).shouldHaveNoInteractions();
+    }
+
     @Test
     public void should_fail_when_mock_had_unwanted_interactions() {
         mock.booleanObjectReturningMethod();
diff --git a/src/test/java/org/mockitousage/misuse/InvalidUsageTest.java b/src/test/java/org/mockitousage/misuse/InvalidUsageTest.java
index 1ba6e99e1f..c2342d7a3c 100644
--- a/src/test/java/org/mockitousage/misuse/InvalidUsageTest.java
+++ b/src/test/java/org/mockitousage/misuse/InvalidUsageTest.java
@@ -37,6 +37,11 @@ public void shouldRequireArgumentsWhenVerifyingZeroInteractions() {
         verifyZeroInteractions();
     }
 
+    @Test(expected=MockitoException.class)
+    public void shouldRequireArgumentsWhenVerifyingNoInteractions() {
+        verifyNoInteractions();
+    }
+
     @Test(expected=MockitoException.class)
     public void shouldNotCreateInOrderObjectWithoutMocks() {
         inOrder();
@@ -104,6 +109,18 @@ public void shouldNotMockObjectMethodsOnInterface() throws Exception {
         verifyZeroInteractions(inter);
     }
 
+    @Test
+    public void shouldNotMockObjectMethodsOnInterfaceVerifyNoInteractions() throws Exception {
+        ObjectLikeInterface inter = mock(ObjectLikeInterface.class);
+
+        inter.equals(null);
+        inter.toString();
+        inter.hashCode();
+
+        verifyNoInteractions(inter);
+    }
+
+    @Test
     public void shouldNotMockObjectMethodsOnClass() throws Exception {
         Object clazz = mock(ObjectLikeInterface.class);
 
@@ -113,4 +130,15 @@ public void shouldNotMockObjectMethodsOnClass() throws Exception {
 
         verifyZeroInteractions(clazz);
     }
+
+    @Test
+    public void shouldNotMockObjectMethodsOnClassVerifyNoInteractions() throws Exception {
+        Object clazz = mock(ObjectLikeInterface.class);
+
+        clazz.equals(null);
+        clazz.toString();
+        clazz.hashCode();
+
+        verifyNoInteractions(clazz);
+    }
 }
diff --git a/src/test/java/org/mockitousage/stacktrace/StackTraceFilteringTest.java b/src/test/java/org/mockitousage/stacktrace/StackTraceFilteringTest.java
index 8ad5ae0ead..2da4492d2b 100644
--- a/src/test/java/org/mockitousage/stacktrace/StackTraceFilteringTest.java
+++ b/src/test/java/org/mockitousage/stacktrace/StackTraceFilteringTest.java
@@ -19,11 +19,7 @@
 import org.mockitoutil.TestBase;
 
 import static junit.framework.TestCase.fail;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
 import static org.mockitoutil.Conditions.firstMethodInStackTrace;
 
 public class StackTraceFilteringTest extends TestBase {
@@ -72,6 +68,17 @@ public void shouldFilterStackTraceOnVerifyZeroInteractions() {
         }
     }
 
+    @Test
+    public void shouldFilterStackTraceOnVerifyNoInteractions() {
+        mock.oneArg(true);
+        try {
+            verifyNoInteractions(mock);
+            fail();
+        } catch (NoInteractionsWanted e) {
+            Assertions.assertThat(e).has(firstMethodInStackTrace("shouldFilterStackTraceOnVerifyNoInteractions"));
+        }
+    }
+
     @Test
     public void shouldFilterStacktraceOnMockitoException() {
         verify(mock);
diff --git a/src/test/java/org/mockitousage/stubbing/BasicStubbingTest.java b/src/test/java/org/mockitousage/stubbing/BasicStubbingTest.java
index faf250d76f..688b12a4a8 100644
--- a/src/test/java/org/mockitousage/stubbing/BasicStubbingTest.java
+++ b/src/test/java/org/mockitousage/stubbing/BasicStubbingTest.java
@@ -66,6 +66,14 @@ public void should_stubbing_not_be_treated_as_interaction() {
         verifyZeroInteractions(mock);
     }
 
+    @Test
+    public void should_stubbing_not_be_treated_as_interaction_verify_no_interactions() {
+        when(mock.simpleMethod("one")).thenThrow(new RuntimeException());
+        doThrow(new RuntimeException()).when(mock).simpleMethod("two");
+
+        verifyNoInteractions(mock);
+    }
+
     @Test
     public void unfinished_stubbing_cleans_up_the_state() {
         reset(mock);
@@ -78,6 +86,18 @@ public void unfinished_stubbing_cleans_up_the_state() {
         verifyZeroInteractions(mock);
     }
 
+    @Test
+    public void unfinished_stubbing_cleans_up_the_state_verify_no_interactions() {
+        reset(mock);
+        try {
+            when("").thenReturn("");
+            fail();
+        } catch (MissingMethodInvocationException e) {}
+
+        //anything that can cause state validation
+        verifyNoInteractions(mock);
+    }
+
     @Test
     public void should_to_string_mock_name() {
         IMethods mock = mock(IMethods.class, "mockie");
diff --git a/src/test/java/org/mockitousage/stubbing/StubbingWithThrowablesTest.java b/src/test/java/org/mockitousage/stubbing/StubbingWithThrowablesTest.java
index 0ccf14f268..b6516048e4 100644
--- a/src/test/java/org/mockitousage/stubbing/StubbingWithThrowablesTest.java
+++ b/src/test/java/org/mockitousage/stubbing/StubbingWithThrowablesTest.java
@@ -212,7 +212,7 @@ public void shouldStubbingWithThrowableFailVerification() {
         when(mock.size()).thenThrow(new RuntimeException());
         doThrow(new RuntimeException()).when(mock).clone();
 
-        verifyZeroInteractions(mock);
+        verifyNoInteractions(mock);
 
         mock.add("test");
 
diff --git a/src/test/java/org/mockitousage/verification/BasicVerificationInOrderTest.java b/src/test/java/org/mockitousage/verification/BasicVerificationInOrderTest.java
index 4268b591ce..d94794e1e8 100644
--- a/src/test/java/org/mockitousage/verification/BasicVerificationInOrderTest.java
+++ b/src/test/java/org/mockitousage/verification/BasicVerificationInOrderTest.java
@@ -264,6 +264,11 @@ public void shouldFailOnVerifyZeroInteractions() {
         verifyZeroInteractions(mockOne);
     }
 
+    @Test(expected = NoInteractionsWanted.class)
+    public void shouldFailOnVerifyNoInteractions() {
+        verifyNoInteractions(mockOne);
+    }
+
     @SuppressWarnings("all")
     @Test(expected = MockitoException.class)
     public void shouldScreamWhenNullPassed() {
diff --git a/src/test/java/org/mockitousage/verification/DescriptiveMessagesWhenVerificationFailsTest.java b/src/test/java/org/mockitousage/verification/DescriptiveMessagesWhenVerificationFailsTest.java
index 72cd98d778..c81f97a66c 100644
--- a/src/test/java/org/mockitousage/verification/DescriptiveMessagesWhenVerificationFailsTest.java
+++ b/src/test/java/org/mockitousage/verification/DescriptiveMessagesWhenVerificationFailsTest.java
@@ -210,6 +210,33 @@ public void should_print_first_unexpected_invocation_when_verifying_zero_interac
         }
     }
 
+    @Test
+    public void should_print_first_unexpected_invocation_when_verifying_no_interactions() {
+        mock.twoArgumentMethod(1, 2);
+        mock.threeArgumentMethod(1, "2", "3");
+
+        try {
+            verifyNoInteractions(mock);
+            fail();
+        } catch (NoInteractionsWanted e) {
+            String expected =
+                    "\n" +
+                    "No interactions wanted here:" +
+                    "\n" +
+                    "-> at";
+
+            assertThat(e).hasMessageContaining(expected);
+
+            String expectedCause =
+                "\n" +
+                "But found these interactions on mock '" + mock + "':" +
+                "\n" +
+                "-> at";
+
+            assertThat(e).hasMessageContaining(expectedCause);
+        }
+    }
+
     @Test
     public void should_print_method_name_when_verifying_at_least_once() throws Exception {
         try {
diff --git a/src/test/java/org/mockitousage/verification/NoMoreInteractionsVerificationTest.java b/src/test/java/org/mockitousage/verification/NoMoreInteractionsVerificationTest.java
index 6382df3a6c..04aef9a408 100644
--- a/src/test/java/org/mockitousage/verification/NoMoreInteractionsVerificationTest.java
+++ b/src/test/java/org/mockitousage/verification/NoMoreInteractionsVerificationTest.java
@@ -58,6 +58,9 @@ public void shouldVerifyNoInteractionsAsManyTimesAsYouWant() throws Exception {
 
         verifyZeroInteractions(mock);
         verifyZeroInteractions(mock);
+
+        verifyNoInteractions(mock);
+        verifyNoInteractions(mock);
     }
 
     @Test
@@ -70,6 +73,16 @@ public void shouldFailZeroInteractionsVerification() throws Exception {
         } catch (NoInteractionsWanted e) {}
     }
 
+    @Test
+    public void shouldFailNoInteractionsVerification() throws Exception {
+        mock.clear();
+
+        try {
+            verifyNoInteractions(mock);
+            fail();
+        } catch (NoInteractionsWanted e) {}
+    }
+
     @Test
     public void shouldFailNoMoreInteractionsVerification() throws Exception {
         mock.clear();
@@ -126,6 +139,25 @@ public void shouldVerifyOneMockButFailOnOther() throws Exception {
         } catch (NoInteractionsWanted e) {}
     }
 
+    @Test
+    public void shouldVerifyOneMockButFailOnOtherVerifyNoInteractions() throws Exception {
+        List<String> list = mock(List.class);
+        Map<String, Integer> map = mock(Map.class);
+
+        list.add("one");
+        list.add("one");
+
+        map.put("one", 1);
+
+        verify(list, times(2)).add("one");
+
+        verifyNoMoreInteractions(list);
+        try {
+            verifyNoInteractions(map);
+            fail();
+        } catch (NoInteractionsWanted e) {}
+    }
+
     @SuppressWarnings("all")
     @Test(expected=MockitoException.class)
     public void verifyNoMoreInteractionsShouldScreamWhenNullPassed() throws Exception {
diff --git a/src/test/java/org/mockitousage/verification/VerificationOnMultipleMocksUsingMatchersTest.java b/src/test/java/org/mockitousage/verification/VerificationOnMultipleMocksUsingMatchersTest.java
index 45bf19d4ff..5a6610aae9 100644
--- a/src/test/java/org/mockitousage/verification/VerificationOnMultipleMocksUsingMatchersTest.java
+++ b/src/test/java/org/mockitousage/verification/VerificationOnMultipleMocksUsingMatchersTest.java
@@ -60,5 +60,6 @@ public void shouldVerifyMultipleMocks() throws Exception {
 
         verifyNoMoreInteractions(list, map);
         verifyZeroInteractions(set);
+        verifyNoInteractions(set);
     }
 }
diff --git a/subprojects/testng/src/test/java/org/mockitousage/testng/ResetMocksInParentTestClassTooTest.java b/subprojects/testng/src/test/java/org/mockitousage/testng/ResetMocksInParentTestClassTooTest.java
index e9dd50a83a..55fef7adbf 100644
--- a/subprojects/testng/src/test/java/org/mockitousage/testng/ResetMocksInParentTestClassTooTest.java
+++ b/subprojects/testng/src/test/java/org/mockitousage/testng/ResetMocksInParentTestClassTooTest.java
@@ -2,6 +2,7 @@
 
 import org.testng.annotations.Test;
 
+import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.verifyZeroInteractions;
 
 public class ResetMocksInParentTestClassTooTest extends ParentTest {
@@ -15,4 +16,9 @@ public void interact_with_parent_mock() throws Exception {
     public void verify__zero_interaction_with_parent_mock() throws Exception {
         verifyZeroInteractions(parentMockField);
     }
+
+    @Test
+    public void verify__no_interaction_with_parent_mock() throws Exception {
+        verifyNoInteractions(parentMockField);
+    }
 }