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