/* * Copyright (c) 2007 Mockito contributors * This program is made available under the terms of the MIT License. */ package org.mockitousage.debugging; import org.assertj.core.api.Assertions; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.internal.util.MockUtil; import org.mockito.junit.MockitoJUnitRunner; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import static org.junit.Assert.fail; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.*; /** * Tests the verbose logging of invocation on mock methods. * * BEWARE: These tests rely on mocking the standard output. While in a * single-threaded environment the Before/After-contract ensures, that the * original output stream is restored, there is no guarantee for this * in the parallel setting. * Maybe, the test class should be @Ignore'd by default ... */ @RunWith(MockitoJUnitRunner.class) public class VerboseLoggingOfInvocationsOnMockTest { private ByteArrayOutputStream output; private PrintStream original; @Mock UnrelatedClass unrelatedMock; @Before public void setUp() { original = System.out; output = new ByteArrayOutputStream(); System.setOut(new PrintStream(output)); } @After public void tearDown() { System.setOut(original); } @Test public void shouldNotPrintInvocationOnMockWithoutSetting() { // given Foo foo = mock(Foo.class, withSettings().verboseLogging()); // when foo.giveMeSomeString("Klipsch"); unrelatedMock.unrelatedMethod("Apple"); // then Assertions.assertThat(printed()) .doesNotContain(mockName(unrelatedMock)) .doesNotContain("unrelatedMethod") .doesNotContain("Apple"); } @Test public void shouldPrintUnstubbedInvocationOnMockToStdOut() { // given Foo foo = mock(Foo.class, withSettings().verboseLogging()); // when foo.doSomething("Klipsch"); // then Assertions.assertThat(printed()) .contains(getClass().getName()) .contains(mockName(foo)) .contains("doSomething") .contains("Klipsch"); } @Test public void shouldPrintStubbedInvocationOnMockToStdOut() { // given Foo foo = mock(Foo.class, withSettings().verboseLogging()); given(foo.giveMeSomeString("Klipsch")).willReturn("earbuds"); // when foo.giveMeSomeString("Klipsch"); // then Assertions.assertThat(printed()) .contains(getClass().getName()) .contains(mockName(foo)) .contains("giveMeSomeString") .contains("Klipsch") .contains("earbuds"); } @Test public void shouldPrintThrowingInvocationOnMockToStdOut() { // given Foo foo = mock(Foo.class, withSettings().verboseLogging()); doThrow(new ThirdPartyException()).when(foo).doSomething("Klipsch"); try { // when foo.doSomething("Klipsch"); fail("Exception excepted."); } catch (ThirdPartyException e) { // then Assertions.assertThat(printed()) .contains(getClass().getName()) .contains(mockName(foo)) .contains("doSomething") .contains("Klipsch") .contains(ThirdPartyException.class.getName()); } } @Test public void shouldPrintRealInvocationOnSpyToStdOut() { // given FooImpl fooSpy = mock(FooImpl.class, withSettings().spiedInstance(new FooImpl()).verboseLogging()); doCallRealMethod().when(fooSpy).doSomething("Klipsch"); // when fooSpy.doSomething("Klipsch"); // then Assertions.assertThat(printed()) .contains(getClass().getName()) .contains(mockName(fooSpy)) .contains("doSomething") .contains("Klipsch"); } @Test public void usage() { // given Foo foo = mock(Foo.class, withSettings().verboseLogging()); given(foo.giveMeSomeString("Apple")).willReturn( "earbuds"); // when foo.giveMeSomeString("Shure"); foo.giveMeSomeString("Apple"); foo.doSomething("Klipsch"); } private String printed() { return output.toString(); } private String mockName(Object mock) { return MockUtil.getMockName(mock).toString(); } private static class UnrelatedClass { void unrelatedMethod(String anotherStringValue) { } } /** * An exception that isn't defined by Mockito or the JDK and therefore does * not appear in the logging result by chance alone. */ static class ThirdPartyException extends RuntimeException { private static final long serialVersionUID = 2160445705646210847L; } static class FooImpl implements Foo { public String giveMeSomeString(String param) { return null; } public void doSomething(String param) { } } }