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.spies; 6 7 import static org.junit.Assert.assertEquals; 8 import static org.junit.Assert.fail; 9 import static org.mockito.Mockito.doThrow; 10 import static org.mockito.Mockito.spy; 11 import static org.mockito.Mockito.verify; 12 import static org.mockito.Mockito.when; 13 import static org.mockitoutil.Conditions.methodsInStackTrace; 14 15 import org.assertj.core.api.Assertions; 16 import org.junit.Before; 17 import org.junit.Test; 18 import org.mockitoutil.TestBase; 19 20 @SuppressWarnings("unchecked") 21 public class PartialMockingWithSpiesTest extends TestBase { 22 23 @Before pleaseMakeStackTracesClean()24 public void pleaseMakeStackTracesClean() { 25 makeStackTracesClean(); 26 } 27 28 class InheritMe { 29 private String inherited = "100$"; 30 getInherited()31 protected String getInherited() { 32 return inherited; 33 } 34 } 35 36 class Person extends InheritMe { 37 private final Name defaultName = new Name("Default name"); 38 getName()39 public String getName() { 40 return guessName().name; 41 } 42 guessName()43 Name guessName() { 44 return defaultName; 45 } 46 howMuchDidYouInherit()47 public String howMuchDidYouInherit() { 48 return getInherited(); 49 } 50 getNameButDelegateToMethodThatThrows()51 public String getNameButDelegateToMethodThatThrows() { 52 throwSomeException(); 53 return guessName().name; 54 } 55 throwSomeException()56 private void throwSomeException() { 57 throw new RuntimeException("boo"); 58 } 59 } 60 61 class Name { 62 private final String name; 63 Name(String name)64 public Name(String name) { 65 this.name = name; 66 } 67 } 68 69 Person spy = spy(new Person()); 70 71 @Test shouldCallRealMethdsEvenDelegatedToOtherSelfMethod()72 public void shouldCallRealMethdsEvenDelegatedToOtherSelfMethod() { 73 // when 74 String name = spy.getName(); 75 76 // then 77 assertEquals("Default name", name); 78 } 79 80 @Test shouldAllowStubbingOfMethodsThatDelegateToOtherMethods()81 public void shouldAllowStubbingOfMethodsThatDelegateToOtherMethods() { 82 // when 83 when(spy.getName()).thenReturn("foo"); 84 85 // then 86 assertEquals("foo", spy.getName()); 87 } 88 89 @Test shouldAllowStubbingWithThrowablesMethodsThatDelegateToOtherMethods()90 public void shouldAllowStubbingWithThrowablesMethodsThatDelegateToOtherMethods() { 91 // when 92 doThrow(new RuntimeException("appetite for destruction")) 93 .when(spy) 94 .getNameButDelegateToMethodThatThrows(); 95 96 // then 97 try { 98 spy.getNameButDelegateToMethodThatThrows(); 99 fail(); 100 } catch (Exception e) { 101 assertEquals("appetite for destruction", e.getMessage()); 102 } 103 } 104 105 @Test shouldStackTraceGetFilteredOnUserExceptions()106 public void shouldStackTraceGetFilteredOnUserExceptions() { 107 try { 108 // when 109 spy.getNameButDelegateToMethodThatThrows(); 110 fail(); 111 } catch (Throwable t) { 112 // then 113 Assertions.assertThat(t) 114 .has( 115 methodsInStackTrace( 116 "throwSomeException", 117 "getNameButDelegateToMethodThatThrows", 118 "shouldStackTraceGetFilteredOnUserExceptions")); 119 } 120 } 121 122 // @Test //manual verification verifyTheStackTrace()123 public void verifyTheStackTrace() { 124 spy.getNameButDelegateToMethodThatThrows(); 125 } 126 127 @Test shouldVerify()128 public void shouldVerify() { 129 // when 130 spy.getName(); 131 132 // then 133 verify(spy).guessName(); 134 } 135 136 @Test shouldStub()137 public void shouldStub() { 138 // given 139 when(spy.guessName()).thenReturn(new Name("John")); 140 // when 141 String name = spy.getName(); 142 // then 143 assertEquals("John", name); 144 } 145 146 @Test shouldDealWithPrivateFieldsOfSubclasses()147 public void shouldDealWithPrivateFieldsOfSubclasses() { 148 assertEquals("100$", spy.howMuchDidYouInherit()); 149 } 150 } 151