1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 package org.mockitousage.debugging; 6 7 import org.assertj.core.api.Assertions; 8 import org.junit.After; 9 import org.junit.Before; 10 import org.junit.Test; 11 import org.junit.runner.RunWith; 12 import org.mockito.Mock; 13 import org.mockito.internal.util.MockUtil; 14 import org.mockito.junit.MockitoJUnitRunner; 15 16 import java.io.ByteArrayOutputStream; 17 import java.io.PrintStream; 18 19 import static org.junit.Assert.fail; 20 import static org.mockito.BDDMockito.given; 21 import static org.mockito.Mockito.*; 22 23 /** 24 * Tests the verbose logging of invocation on mock methods. 25 * 26 * BEWARE: These tests rely on mocking the standard output. While in a 27 * single-threaded environment the Before/After-contract ensures, that the 28 * original output stream is restored, there is no guarantee for this 29 * in the parallel setting. 30 * Maybe, the test class should be @Ignore'd by default ... 31 */ 32 @RunWith(MockitoJUnitRunner.class) 33 public class VerboseLoggingOfInvocationsOnMockTest { 34 35 private ByteArrayOutputStream output; 36 private PrintStream original; 37 38 @Mock UnrelatedClass unrelatedMock; 39 40 @Before setUp()41 public void setUp() { 42 original = System.out; 43 output = new ByteArrayOutputStream(); 44 System.setOut(new PrintStream(output)); 45 } 46 47 @After tearDown()48 public void tearDown() { 49 System.setOut(original); 50 } 51 52 @Test shouldNotPrintInvocationOnMockWithoutSetting()53 public void shouldNotPrintInvocationOnMockWithoutSetting() { 54 // given 55 Foo foo = mock(Foo.class, withSettings().verboseLogging()); 56 57 // when 58 foo.giveMeSomeString("Klipsch"); 59 unrelatedMock.unrelatedMethod("Apple"); 60 61 // then 62 Assertions.assertThat(printed()) 63 .doesNotContain(mockName(unrelatedMock)) 64 .doesNotContain("unrelatedMethod") 65 .doesNotContain("Apple"); 66 } 67 68 @Test shouldPrintUnstubbedInvocationOnMockToStdOut()69 public void shouldPrintUnstubbedInvocationOnMockToStdOut() { 70 // given 71 Foo foo = mock(Foo.class, withSettings().verboseLogging()); 72 73 // when 74 foo.doSomething("Klipsch"); 75 76 // then 77 Assertions.assertThat(printed()) 78 .contains(getClass().getName()) 79 .contains(mockName(foo)) 80 .contains("doSomething") 81 .contains("Klipsch"); 82 } 83 84 @Test shouldPrintStubbedInvocationOnMockToStdOut()85 public void shouldPrintStubbedInvocationOnMockToStdOut() { 86 // given 87 Foo foo = mock(Foo.class, withSettings().verboseLogging()); 88 given(foo.giveMeSomeString("Klipsch")).willReturn("earbuds"); 89 90 // when 91 foo.giveMeSomeString("Klipsch"); 92 93 // then 94 Assertions.assertThat(printed()) 95 .contains(getClass().getName()) 96 .contains(mockName(foo)) 97 .contains("giveMeSomeString") 98 .contains("Klipsch") 99 .contains("earbuds"); 100 } 101 102 @Test shouldPrintThrowingInvocationOnMockToStdOut()103 public void shouldPrintThrowingInvocationOnMockToStdOut() { 104 // given 105 Foo foo = mock(Foo.class, withSettings().verboseLogging()); 106 doThrow(new ThirdPartyException()).when(foo).doSomething("Klipsch"); 107 108 try { 109 // when 110 foo.doSomething("Klipsch"); 111 fail("Exception excepted."); 112 } catch (ThirdPartyException e) { 113 // then 114 Assertions.assertThat(printed()) 115 .contains(getClass().getName()) 116 .contains(mockName(foo)) 117 .contains("doSomething") 118 .contains("Klipsch") 119 .contains(ThirdPartyException.class.getName()); 120 } 121 } 122 123 @Test shouldPrintRealInvocationOnSpyToStdOut()124 public void shouldPrintRealInvocationOnSpyToStdOut() { 125 // given 126 FooImpl fooSpy = mock(FooImpl.class, 127 withSettings().spiedInstance(new FooImpl()).verboseLogging()); 128 doCallRealMethod().when(fooSpy).doSomething("Klipsch"); 129 130 // when 131 fooSpy.doSomething("Klipsch"); 132 133 // then 134 Assertions.assertThat(printed()) 135 .contains(getClass().getName()) 136 .contains(mockName(fooSpy)) 137 .contains("doSomething") 138 .contains("Klipsch"); 139 } 140 141 @Test usage()142 public void usage() { 143 // given 144 Foo foo = mock(Foo.class, withSettings().verboseLogging()); 145 given(foo.giveMeSomeString("Apple")).willReturn( 146 "earbuds"); 147 148 // when 149 foo.giveMeSomeString("Shure"); 150 foo.giveMeSomeString("Apple"); 151 foo.doSomething("Klipsch"); 152 } 153 printed()154 private String printed() { 155 return output.toString(); 156 } 157 mockName(Object mock)158 private String mockName(Object mock) { 159 return MockUtil.getMockName(mock).toString(); 160 } 161 162 private static class UnrelatedClass { unrelatedMethod(String anotherStringValue)163 void unrelatedMethod(String anotherStringValue) { 164 } 165 } 166 167 /** 168 * An exception that isn't defined by Mockito or the JDK and therefore does 169 * not appear in the logging result by chance alone. 170 */ 171 static class ThirdPartyException extends RuntimeException { 172 private static final long serialVersionUID = 2160445705646210847L; 173 } 174 175 static class FooImpl implements Foo { giveMeSomeString(String param)176 public String giveMeSomeString(String param) { 177 return null; 178 } 179 doSomething(String param)180 public void doSomething(String param) { 181 } 182 } 183 } 184