12637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin/*
22637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin * Copyright (c) 2007 Mockito contributors
32637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin * This program is made available under the terms of the MIT License.
42637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin */
52637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
62637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinpackage org.mockitousage.spies;
72637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
82637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.assertj.core.api.Assertions;
92637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.junit.Before;
102637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.junit.Test;
112637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockitoutil.TestBase;
122637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
132637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport static junit.framework.TestCase.assertEquals;
142637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport static junit.framework.TestCase.fail;
152637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport static org.mockito.Mockito.doThrow;
162637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport static org.mockito.Mockito.spy;
172637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport static org.mockito.Mockito.verify;
182637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport static org.mockito.Mockito.when;
192637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport static org.mockitoutil.Conditions.methodsInStackTrace;
202637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
212637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin@SuppressWarnings("unchecked")
222637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinpublic class PartialMockingWithSpiesTest extends TestBase {
232637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
242637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Before
252637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void pleaseMakeStackTracesClean() {
262637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        makeStackTracesClean();
272637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
282637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
292637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    class InheritMe {
302637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        private String inherited = "100$";
312637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        protected String getInherited() {
322637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            return inherited;
332637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
342637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
352637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
362637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    class Person extends InheritMe {
372637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        private final Name defaultName = new Name("Default name");
382637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
392637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        public String getName() {
402637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            return guessName().name;
412637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
422637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
432637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        Name guessName() {
442637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            return defaultName;
452637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
462637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
472637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        public String howMuchDidYouInherit() {
482637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            return getInherited();
492637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
502637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
512637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        public String getNameButDelegateToMethodThatThrows() {
522637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            throwSomeException();
532637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            return guessName().name;
542637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
552637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
562637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        private void throwSomeException() {
572637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            throw new RuntimeException("boo");
582637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
592637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
602637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
612637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    class Name {
622637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        private final String name;
632637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
642637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        public Name(String name) {
652637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            this.name = name;
662637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
672637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
682637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
692637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    Person spy = spy(new Person());
702637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
712637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
722637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void shouldCallRealMethdsEvenDelegatedToOtherSelfMethod() {
732637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // when
742637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        String name = spy.getName();
752637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
762637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // then
772637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals("Default name", name);
782637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
792637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
802637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
812637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void shouldAllowStubbingOfMethodsThatDelegateToOtherMethods() {
822637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // when
832637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        when(spy.getName()).thenReturn("foo");
842637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
852637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // then
862637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals("foo", spy.getName());
872637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
882637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
892637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
902637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void shouldAllowStubbingWithThrowablesMethodsThatDelegateToOtherMethods() {
912637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // when
922637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        doThrow(new RuntimeException("appetite for destruction"))
932637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            .when(spy).getNameButDelegateToMethodThatThrows();
942637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
952637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // then
962637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        try {
972637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            spy.getNameButDelegateToMethodThatThrows();
982637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            fail();
992637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        } catch(Exception e) {
1002637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            assertEquals("appetite for destruction", e.getMessage());
1012637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
1022637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1032637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1042637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
1052637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void shouldStackTraceGetFilteredOnUserExceptions() {
1062637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        try {
1072637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            // when
1082637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            spy.getNameButDelegateToMethodThatThrows();
1092637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            fail();
1102637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        } catch (Throwable t) {
1112637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            // then
1122637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            Assertions.assertThat(t).has(methodsInStackTrace(
1132637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                    "throwSomeException",
1142637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                    "getNameButDelegateToMethodThatThrows",
1152637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                    "shouldStackTraceGetFilteredOnUserExceptions"
1162637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                    ));
1172637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
1182637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1192637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1202637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin//    @Test //manual verification
1212637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void verifyTheStackTrace() {
1222637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        spy.getNameButDelegateToMethodThatThrows();
1232637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1242637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1252637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
1262637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void shouldVerify() {
1272637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // when
1282637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        spy.getName();
1292637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1302637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // then
1312637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        verify(spy).guessName();
1322637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1332637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1342637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
1352637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void shouldStub() {
1362637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // given
1372637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        when(spy.guessName()).thenReturn(new Name("John"));
1382637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // when
1392637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        String name = spy.getName();
1402637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // then
1412637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals("John", name);
1422637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1432637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1442637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
1452637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void shouldDealWithPrivateFieldsOfSubclasses() {
1462637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals("100$", spy.howMuchDidYouInherit());
1472637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1482637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin}
149