Repository: mockito/mockito
Issue: new MockingDetails.printInvocations() API for debugging tests and edge cases
Labels: new feature

Let's add new MockingDetails.printInvocations() API. We already provide it silently via Mockito.debug().printInvocations(). Since the code is in place, let's expose it and get rid of the Mockito.debug()
- [ ] move Mockito.debug().printInvocations() to MockingDetails, move tests, too
- [ ] document new API addition somewhere (find place if there isn't any)
- [ ] document removal of the API (find place for removed API if any)


Issue comments:

Pull request review comments:
`out` could be `StringBuilder` instead of just `String`.

Formatting.

`String.format()` to improve readability?

Why not to mark it with `@Override` to force a deletion? AFAIR Mockito does not support Java 5 any longer.

It would be nice to prefer AssertJ assertions over Junit they have a better API and allow chaining. Not a blocker to merge though.

Actually it's the reverse `assertThat(value).isEqualTo(expected)`

@szczepiq It seems to remain not fixed.


Patch that resolved the issue:
diff --git a/src/main/java/org/mockito/MockingDetails.java b/src/main/java/org/mockito/MockingDetails.java
index 794582dc6a..6ac617c55d 100644
--- a/src/main/java/org/mockito/MockingDetails.java
+++ b/src/main/java/org/mockito/MockingDetails.java
@@ -14,6 +14,7 @@
 /**
  * Provides mocking information.
  * For example, you can identify whether a particular object is either a mock or a spy.
+ * For examples and more information please refer to the javadoc of the individual methods on this class.
  *
  * @since 1.9.5
  */
@@ -84,7 +85,27 @@ public interface MockingDetails {
      * <p>
      * This method throws meaningful exception when object wrapped by MockingDetails is not a mock.
      *
-     * @since 2.2.0
+     * @since 2.2.3
      */
     Collection<Stubbing> getStubbings();
+
+    /**
+     * Returns printing-friendly list of the invocations that occurred with the mock object.
+     * Additionally, this method prints stubbing information, including unused stubbings.
+     * For more information about unused stubbing detection see {@link MockitoHint}.
+     * <p>
+     * You can use this method for debugging,
+     *  print the output of this method to the console to find out about all interactions with the mock.
+     * <p>
+     * Content that is printed is subject to change as we discover better ways of presenting important mock information.
+     * Don't write code that depends on the output of this method.
+     * If you need to know about interactions and stubbings, use {@link #getStubbings()} and {@link #getInvocations()}.
+     * <p>
+     * This method was moved from the deprecated and semi-hidden type {@link MockitoDebugger}.
+     * <p>
+     * This method throws meaningful exception when object wrapped by MockingDetails is not a mock.
+     *
+     * @since 2.2.6
+     */
+    String printInvocations();
 }
diff --git a/src/main/java/org/mockito/Mockito.java b/src/main/java/org/mockito/Mockito.java
index 47d08e4991..684add4b58 100644
--- a/src/main/java/org/mockito/Mockito.java
+++ b/src/main/java/org/mockito/Mockito.java
@@ -59,7 +59,7 @@
  *      <a href="#23">23. Automatic instantiation of <code>&#064;Spies</code>, <code>&#064;InjectMocks</code> and constructor injection goodness (Since 1.9.0)</a><br/>
  *      <a href="#24">24. One-liner stubs (Since 1.9.0)</a><br/>
  *      <a href="#25">25. Verification ignoring stubs (Since 1.9.0)</a><br/>
- *      <a href="#26">26. Mocking details (Improved in 2.2.0)</a><br/>
+ *      <a href="#26">26. Mocking details (Improved in 2.2.x)</a><br/>
  *      <a href="#27">27. Delegate calls to real instance (Since 1.9.5)</a><br/>
  *      <a href="#28">28. <code>MockMaker</code> API (Since 1.9.5)</a><br/>
  *      <a href="#29">29. BDD style verification (Since 1.10.0)</a><br/>
@@ -889,7 +889,7 @@
  *
  *
  *
- * <h3 id="26">26. <a class="meaningful_link" href="#mocking_details">Mocking details</a> (Improved in 2.2.0)</h3>
+ * <h3 id="26">26. <a class="meaningful_link" href="#mocking_details">Mocking details</a> (Improved in 2.2.x)</h3>
  * <p>
  *
  * Mockito offers API to inspect the details of a mock object.
@@ -901,14 +901,17 @@
  *   Mockito.mockingDetails(someObject).isSpy();
  *
  *   //Getting details like type to mock or default answer:
- *   MockingDetails details = mockingDetails(someObject)
+ *   MockingDetails details = mockingDetails(mock);
  *   details.getMockCreationSettings().getTypeToMock();
  *   details.getMockCreationSettings().getDefaultAnswer();
  *
  *   //Getting interactions and stubbings of the mock:
- *   MockingDetails details = mockingDetails(someObject)
+ *   MockingDetails details = mockingDetails(mock);
  *   details.getInteractions();
  *   details.getStubbings();
+ *
+ *   //Printing all interactions (including stubbing, unused stubs)
+ *   System.out.println(mockingDetails(mock).printInvocations());
  * </code></pre>
  *
  * For more information see javadoc for {@link MockingDetails}.
@@ -2649,9 +2652,7 @@ public static VerificationMode description(String description) {
     }
 
     /**
-     * This API will move soon to a different place.
-     * See <a href="https://github.com/mockito/mockito/issues/577">issue 577</a>.
-     * See also <a href="https://github.com/mockito/mockito/issues/542">issue 542</a>.
+     * @deprecated - please use {@link MockingDetails#printInvocations()}.
      */
     @Deprecated
     static MockitoDebugger debug() {
diff --git a/src/main/java/org/mockito/MockitoDebugger.java b/src/main/java/org/mockito/MockitoDebugger.java
index c24d633dfc..46a41762b4 100644
--- a/src/main/java/org/mockito/MockitoDebugger.java
+++ b/src/main/java/org/mockito/MockitoDebugger.java
@@ -4,10 +4,15 @@
  */
 package org.mockito;
 
+/**
+ * @deprecated - please use {@link MockingDetails#printInvocations()}.
+ */
+@Deprecated
 public interface MockitoDebugger {
 
-    //Prints all interactions with mock. Also prints stubbing information.
-    //You can put it in your 'tearDown' method
+    /**
+     * @deprecated - please use {@link MockingDetails#printInvocations()}.
+     */
+    @Deprecated
     String printInvocations(Object ... mocks);
-
 }
\ No newline at end of file
diff --git a/src/main/java/org/mockito/internal/debugging/InvocationsPrinter.java b/src/main/java/org/mockito/internal/debugging/InvocationsPrinter.java
new file mode 100644
index 0000000000..b0df32af87
--- /dev/null
+++ b/src/main/java/org/mockito/internal/debugging/InvocationsPrinter.java
@@ -0,0 +1,54 @@
+package org.mockito.internal.debugging;
+
+import org.mockito.Mockito;
+import org.mockito.internal.util.collections.ListUtil;
+import org.mockito.invocation.Invocation;
+import org.mockito.stubbing.Stubbing;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+/**
+ * Prints invocations in human-readable, printable way
+ */
+public class InvocationsPrinter {
+
+    public String printInvocations(Object mock) {
+        Collection<Invocation> invocations = Mockito.mockingDetails(mock).getInvocations();
+        Collection<Stubbing> stubbings = Mockito.mockingDetails(mock).getStubbings();
+        if (invocations.isEmpty() && stubbings.isEmpty()) {
+            return "No interactions and stubbings found for mock: " + mock;
+        }
+
+        StringBuilder sb = new StringBuilder();
+        int x = 1;
+        for(Invocation i:invocations) {
+            if (x == 1) {
+                sb.append("[Mockito] Interactions of: ").append(mock).append("\n");
+            }
+            sb.append(" ").append(x++).append(". ").append(i.toString()).append("\n");
+            sb.append("  ").append(i.getLocation()).append("\n");
+            if (i.stubInfo() != null) {
+                sb.append("   - stubbed ").append(i.stubInfo().stubbedAt()).append("\n");
+            }
+        }
+
+        LinkedList<Stubbing> unused = ListUtil.filter(stubbings, new ListUtil.Filter<Stubbing>() {
+            public boolean isOut(Stubbing s) {
+                return s.wasUsed();
+            }
+        });
+
+        if (unused.isEmpty()) {
+            return sb.toString();
+        }
+        sb.append("[Mockito] Unused stubbings of: " + mock).append("\n");
+
+        x = 1;
+        for(Stubbing s:stubbings) {
+            sb.append(" ").append(x++).append(". ").append(s.getInvocation()).append("\n");
+            sb.append("  - stubbed ").append(s.getInvocation().getLocation()).append("\n");
+        }
+        return sb.toString();
+    }
+}
diff --git a/src/main/java/org/mockito/internal/debugging/MockitoDebuggerImpl.java b/src/main/java/org/mockito/internal/debugging/MockitoDebuggerImpl.java
index 8a8a056b7e..35e7e7b7a9 100644
--- a/src/main/java/org/mockito/internal/debugging/MockitoDebuggerImpl.java
+++ b/src/main/java/org/mockito/internal/debugging/MockitoDebuggerImpl.java
@@ -17,6 +17,10 @@ public class MockitoDebuggerImpl implements MockitoDebugger {
 
     private final UnusedStubsFinder unusedStubsFinder = new UnusedStubsFinder();
 
+    /**
+     * TODO: when MockitoDebugger is deleted, delete this implementation, too
+     */
+    @Deprecated
     public String printInvocations(Object ... mocks) {
         String out = "";
         List<Invocation> invocations = AllInvocationsFinder.find(asList(mocks));
diff --git a/src/main/java/org/mockito/internal/debugging/WarningsCollector.java b/src/main/java/org/mockito/internal/debugging/WarningsCollector.java
index 725da1d740..e9418869e3 100644
--- a/src/main/java/org/mockito/internal/debugging/WarningsCollector.java
+++ b/src/main/java/org/mockito/internal/debugging/WarningsCollector.java
@@ -12,6 +12,7 @@
 import java.util.LinkedList;
 import java.util.List;
 
+@Deprecated
 public class WarningsCollector {
    
     private final List<Object> createdMocks;
diff --git a/src/main/java/org/mockito/internal/invocation/UnusedStubsFinder.java b/src/main/java/org/mockito/internal/invocation/UnusedStubsFinder.java
index 4d515af478..21d3b27dd2 100644
--- a/src/main/java/org/mockito/internal/invocation/UnusedStubsFinder.java
+++ b/src/main/java/org/mockito/internal/invocation/UnusedStubsFinder.java
@@ -12,6 +12,7 @@
 
 import java.util.*;
 
+@Deprecated
 public class UnusedStubsFinder {
 
     /**
diff --git a/src/main/java/org/mockito/internal/util/DefaultMockingDetails.java b/src/main/java/org/mockito/internal/util/DefaultMockingDetails.java
index 5b485891d6..7114a46d21 100644
--- a/src/main/java/org/mockito/internal/util/DefaultMockingDetails.java
+++ b/src/main/java/org/mockito/internal/util/DefaultMockingDetails.java
@@ -7,6 +7,7 @@
 import org.mockito.MockingDetails;
 import org.mockito.exceptions.misusing.NotAMockException;
 import org.mockito.internal.InternalMockHandler;
+import org.mockito.internal.debugging.InvocationsPrinter;
 import org.mockito.stubbing.Stubbing;
 import org.mockito.internal.stubbing.StubbingComparator;
 import org.mockito.invocation.Invocation;
@@ -58,6 +59,12 @@ public Collection<Stubbing> getStubbings() {
         return out;
     }
 
+    @Override
+    public String printInvocations() {
+        assertGoodMock();
+        return new InvocationsPrinter().printInvocations(toInspect);
+    }
+
     private InternalMockHandler<Object> mockHandler() {
         assertGoodMock();
         return getMockHandler(toInspect);
diff --git a/src/main/java/org/mockito/stubbing/Stubbing.java b/src/main/java/org/mockito/stubbing/Stubbing.java
index 6e761382af..795e8ed485 100644
--- a/src/main/java/org/mockito/stubbing/Stubbing.java
+++ b/src/main/java/org/mockito/stubbing/Stubbing.java
@@ -7,7 +7,7 @@
  * Stubbing declared on the mock object.
  * See detailed description including sample code and use cases see javadoc for {@link MockingDetails#getStubbings()}.
  *
- * @since 2.2.0
+ * @since 2.2.3
  */
 public interface Stubbing {
 
@@ -21,7 +21,7 @@ public interface Stubbing {
      * <p>
      * To understand how this method is useful, see the description at {@link MockingDetails#getStubbings()}.
      *
-     * @since 2.2.0
+     * @since 2.2.3
      */
     Invocation getInvocation();
 
@@ -37,7 +37,7 @@ public interface Stubbing {
      * <p>
      * To understand how this method is useful, see the description at {@link MockingDetails#getStubbings()}.
      *
-     * @since 2.2.0
+     * @since 2.2.3
      */
     boolean wasUsed();
 }


Test patch:
diff --git a/src/test/java/org/mockito/internal/util/DefaultMockingDetailsTest.java b/src/test/java/org/mockito/internal/util/DefaultMockingDetailsTest.java
index 4de9518b36..8af561bb3e 100644
--- a/src/test/java/org/mockito/internal/util/DefaultMockingDetailsTest.java
+++ b/src/test/java/org/mockito/internal/util/DefaultMockingDetailsTest.java
@@ -15,8 +15,10 @@
 
 import static junit.framework.TestCase.assertFalse;
 import static junit.framework.TestCase.fail;
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.BDDMockito.given;
 import static org.mockito.Mockito.*;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.withSettings;
@@ -163,6 +165,33 @@ public void manipulating_stubbings_explicitly_is_safe() {
         assertEquals(1, mockingDetails(mock).getStubbings().size());
     }
 
+    @Test
+    public void prints_invocations() throws Exception {
+        //given
+        given(mock.simpleMethod("different arg")).willReturn("foo");
+        mock.simpleMethod("arg");
+
+        //when
+        String log = Mockito.mockingDetails(mock).printInvocations();
+
+        //then
+        assertThat(log).containsIgnoringCase("unused");
+        assertThat(log).containsIgnoringCase("mock.simpleMethod(\"arg\")");
+        assertThat(log).containsIgnoringCase("mock.simpleMethod(\"different arg\")");
+    }
+
+    @Test
+    public void fails_when_printin_invocations_from_non_mock() {
+        try {
+            //when
+            mockingDetails(new Object()).printInvocations();
+            //then
+            fail();
+        } catch (NotAMockException e) {
+            TestCase.assertEquals("Argument passed to Mockito.mockingDetails() should be a mock, but is an instance of class java.lang.Object!", e.getMessage());
+        }
+    }
+
     public class Foo { }
     public interface Bar { }
     public static class Gork { }
diff --git a/src/test/java/org/mockitousage/debugging/InvocationsPrinterTest.java b/src/test/java/org/mockitousage/debugging/InvocationsPrinterTest.java
new file mode 100644
index 0000000000..9d8bacd3e2
--- /dev/null
+++ b/src/test/java/org/mockitousage/debugging/InvocationsPrinterTest.java
@@ -0,0 +1,83 @@
+package org.mockitousage.debugging;
+
+import org.assertj.core.api.Assertions;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.internal.debugging.InvocationsPrinter;
+import org.mockitousage.IMethods;
+import org.mockitoutil.TestBase;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+public class InvocationsPrinterTest extends TestBase {
+
+    @Mock IMethods mock;
+
+    @Test public void no_invocations() {
+        Assert.assertEquals("No interactions and stubbings found for mock: mock", new InvocationsPrinter().printInvocations(mock));
+    }
+
+    @Test public void prints_invocations() {
+        mock.simpleMethod(100);
+        triggerInteraction();
+
+        assertThat(filterLineNo("[Mockito] Interactions of: mock\n" +
+                        " 1. mock.simpleMethod(100);\n" +
+                        "  -> at org.mockitousage.debugging.InvocationsPrinterTest.prints_invocations(InvocationsPrinterTest.java:0)\n" +
+                        " 2. mock.otherMethod();\n" +
+                        "  -> at org.mockitousage.debugging.InvocationsPrinterTest.triggerInteraction(InvocationsPrinterTest.java:0)\n"))
+                .isEqualTo(filterLineNo(new InvocationsPrinter().printInvocations(mock)));
+    }
+
+    @Test public void prints_stubbings() {
+        triggerStubbing();
+
+        assertThat(filterLineNo("[Mockito] Unused stubbings of: mock\n" +
+                " 1. mock.simpleMethod(\"a\");\n" +
+                "  - stubbed -> at org.mockitousage.debugging.InvocationsPrinterTest.triggerStubbing(InvocationsPrinterTest.java:70)\n"))
+                .isEqualTo(filterLineNo(new InvocationsPrinter().printInvocations(mock)));
+    }
+
+    @Test public void prints_invocations_and_stubbings() {
+        triggerStubbing();
+
+        mock.simpleMethod("a");
+        triggerInteraction();
+
+        assertThat(filterLineNo("[Mockito] Interactions of: mock\n" +
+                        " 1. mock.simpleMethod(\"a\");\n" +
+                        "  -> at org.mockitousage.debugging.InvocationsPrinterTest.prints_invocations_and_stubbings(InvocationsPrinterTest.java:49)\n" +
+                        "   - stubbed -> at org.mockitousage.debugging.InvocationsPrinterTest.triggerStubbing(InvocationsPrinterTest.java:73)\n" +
+                        " 2. mock.otherMethod();\n" +
+                        "  -> at org.mockitousage.debugging.InvocationsPrinterTest.triggerInteraction(InvocationsPrinterTest.java:34)\n"))
+                .isEqualTo(filterLineNo(new InvocationsPrinter().printInvocations(mock)));
+    }
+
+    @Test public void prints_invocations_and_unused_stubbings() {
+        triggerStubbing();
+
+        mock.simpleMethod("b");
+        triggerInteraction();
+
+        assertThat(filterLineNo("[Mockito] Interactions of: mock\n" +
+                " 1. mock.simpleMethod(\"b\");\n" +
+                "  -> at org.mockitousage.debugging.InvocationsPrinterTest.prints_invocations_and_unused_stubbings(InvocationsPrinterTest.java:55)\n" +
+                " 2. mock.otherMethod();\n" +
+                "  -> at org.mockitousage.debugging.InvocationsPrinterTest.triggerInteraction(InvocationsPrinterTest.java:34)\n" +
+                "[Mockito] Unused stubbings of: mock\n" +
+                " 1. mock.simpleMethod(\"a\");\n" +
+                "  - stubbed -> at org.mockitousage.debugging.InvocationsPrinterTest.triggerStubbing(InvocationsPrinterTest.java:62)\n"))
+                .isEqualTo(filterLineNo(new InvocationsPrinter().printInvocations(mock)));
+    }
+
+    private void triggerInteraction() {
+        mock.otherMethod();
+    }
+
+    private void triggerStubbing() {
+        when(mock.simpleMethod("a")).thenReturn("x");
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/mockitousage/debugging/PrintingInvocationsDetectsUnusedStubTest.java b/src/test/java/org/mockitousage/debugging/PrintingInvocationsDetectsUnusedStubTest.java
deleted file mode 100644
index 1d7748e4a7..0000000000
--- a/src/test/java/org/mockitousage/debugging/PrintingInvocationsDetectsUnusedStubTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockitousage.debugging;
-
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockitoutil.TestBase;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.BDDMockito.given;
-
-public class PrintingInvocationsDetectsUnusedStubTest extends TestBase {
-
-    @Mock Foo mock;
-    @Mock Foo mockTwo;
-
-    @Test
-    public void shouldDetectUnusedStubbingWhenPrinting() throws Exception {
-        //given
-        given(mock.giveMeSomeString("different arg")).willReturn("foo");
-        mock.giveMeSomeString("arg");
-
-        //when
-        String log = NewMockito.debug().printInvocations(mock, mockTwo);
-
-        //then
-        assertThat(log).containsIgnoringCase("unused");
-    }
-}
\ No newline at end of file
diff --git a/src/test/java/org/mockitousage/debugging/PrintingInvocationsWhenEverythingOkTest.java b/src/test/java/org/mockitousage/debugging/PrintingInvocationsWhenEverythingOkTest.java
deleted file mode 100644
index 49f1b5b8d1..0000000000
--- a/src/test/java/org/mockitousage/debugging/PrintingInvocationsWhenEverythingOkTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockitousage.debugging;
-
-import org.junit.After;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockitoutil.TestBase;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.BDDMockito.verify;
-
-public class PrintingInvocationsWhenEverythingOkTest extends TestBase {
-
-    @Mock Foo mock;
-    @Mock Foo mockTwo;
-
-    @Test
-    public void shouldPrintInvocationsWhenStubbingNotUsed() throws Exception {
-        //given
-        performStubbing();
-        //when
-        businessLogicWithAsking("arg");
-        //then
-        verify(mockTwo).doSomething("foo");
-    }
-
-    private void performStubbing() {
-        given(mock.giveMeSomeString("arg")).willReturn("foo");
-    }
-
-    private void businessLogicWithAsking(String name) {
-        String out = mock.giveMeSomeString(name);
-        businessLogicWithTelling(out);
-    }
-
-    private void businessLogicWithTelling(String out) {
-        mockTwo.doSomething(out);
-    }
-
-    @After
-    public void printInvocations() {
-        String log = NewMockito.debug().printInvocations(mock, mockTwo);
-        //asking
-        assertThat(log)
-            .contains("giveMeSomeString(\"arg\")")
-            .contains(".businessLogicWithAsking(");
-        //telling
-        assertThat(log)
-            .contains("doSomething(\"foo\")")
-            .contains(".businessLogicWithTelling(");
-        //stubbing
-        assertThat(log)
-            .contains("giveMeSomeString(\"arg\")")
-            .contains(".performStubbing(", log);
-    }
-}
\ No newline at end of file
diff --git a/src/test/java/org/mockitousage/debugging/PrintingInvocationsWhenStubNotUsedTest.java b/src/test/java/org/mockitousage/debugging/PrintingInvocationsWhenStubNotUsedTest.java
deleted file mode 100644
index 8b22ffec81..0000000000
--- a/src/test/java/org/mockitousage/debugging/PrintingInvocationsWhenStubNotUsedTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockitousage.debugging;
-
-import org.junit.After;
-import org.junit.Test;
-import org.mockito.exceptions.verification.junit.ArgumentsAreDifferent;
-import org.mockitoutil.TestBase;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.BDDMockito.*;
-
-public class PrintingInvocationsWhenStubNotUsedTest extends TestBase {
-
-    Foo mock = mock(Foo.class);
-    Foo mockTwo = mock(Foo.class);
-
-    @Test(expected = ArgumentsAreDifferent.class)
-    public void shouldPrintInvocationsWhenStubbingNotUsed() throws Exception {
-        //given
-        performStubbing();
-        //when
-        businessLogicWithAsking("arg");
-        //then
-        verify(mockTwo).doSomething("foo");
-    }
-
-    private void performStubbing() {
-        given(mock.giveMeSomeString("different arg")).willReturn("foo");
-    }
-
-    private void businessLogicWithAsking(String name) {
-        String out = mock.giveMeSomeString(name);
-        businessLogicWithTelling(out);
-    }
-
-    private void businessLogicWithTelling(String out) {
-        mockTwo.doSomething(out);
-    }
-
-    @After
-    public void printInvocations() {
-        String log = NewMockito.debug().printInvocations(mock, mockTwo);
-        //asking
-        assertThat(log)
-            .contains("giveMeSomeString(\"arg\")")
-            .contains(".businessLogicWithAsking(");
-        //telling
-        assertThat(log)
-            .contains("doSomething(null)")
-            .contains(".businessLogicWithTelling(");
-        //stubbing
-        assertThat(log)
-            .contains("giveMeSomeString(\"different arg\")")
-            .contains(".performStubbing(");
-    }
-}
\ No newline at end of file