1 /*
2  * Copyright (c) 2017 Mockito contributors
3  * This program is made available under the terms of the MIT License.
4  */
5 package org.mockito.internal.util;
6 
7 import org.junit.Before;
8 import org.junit.Test;
9 import org.mockito.Mock;
10 import org.mockito.Mockito;
11 import org.mockito.MockitoAnnotations;
12 import org.mockito.Spy;
13 import org.mockito.exceptions.misusing.NotAMockException;
14 import org.mockito.stubbing.Stubbing;
15 import org.mockitousage.IMethods;
16 
17 import java.util.Collection;
18 
19 import static org.junit.Assert.assertFalse;
20 import static org.junit.Assert.fail;
21 import static org.assertj.core.api.Assertions.assertThat;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertTrue;
24 import static org.mockito.BDDMockito.given;
25 import static org.mockito.Mockito.mock;
26 import static org.mockito.Mockito.mockingDetails;
27 import static org.mockito.Mockito.spy;
28 import static org.mockito.Mockito.when;
29 import static org.mockito.Mockito.withSettings;
30 
31 @SuppressWarnings("unchecked")
32 public class DefaultMockingDetailsTest {
33 
34     @Mock private Foo foo;
35     @Mock private Bar bar;
36     @Mock private IMethods mock;
37     @Spy private Gork gork;
38 
before()39     @Before public void before() {
40         MockitoAnnotations.initMocks(this);
41     }
42 
43     @Test
should_provide_original_mock()44     public void should_provide_original_mock() throws Exception {
45         //expect
46         assertEquals(mockingDetails(foo).getMock(), foo);
47         assertEquals(mockingDetails(null).getMock(), null);
48     }
49 
50     @Test
should_know_spy()51     public void should_know_spy(){
52         assertTrue(mockingDetails(gork).isMock());
53         assertTrue(mockingDetails(spy( new Gork())).isMock());
54         assertTrue(mockingDetails(spy(Gork.class)).isMock());
55         assertTrue(mockingDetails(mock(Gork.class, withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS))).isMock());
56     }
57 
58     @Test
should_know_mock()59     public void should_know_mock(){
60         assertTrue(mockingDetails(foo).isMock());
61         assertTrue(mockingDetails(mock(Foo.class)).isMock());
62         assertFalse(mockingDetails(foo).isSpy());
63         assertFalse(mockingDetails(mock(Foo.class)).isSpy());
64     }
65 
66     @Test
should_handle_non_mocks()67     public void should_handle_non_mocks() {
68         assertFalse(mockingDetails("non mock").isSpy());
69         assertFalse(mockingDetails("non mock").isMock());
70 
71         assertFalse(mockingDetails(null).isSpy());
72         assertFalse(mockingDetails(null).isMock());
73     }
74 
75     @Test
should_check_that_a_spy_is_also_a_mock()76     public void should_check_that_a_spy_is_also_a_mock() throws Exception {
77         assertEquals(true, mockingDetails(gork).isMock());
78     }
79 
80     @Test
provides_invocations()81     public void provides_invocations() {
82         //when
83         mock.simpleMethod(10);
84         mock.otherMethod();
85 
86         //then
87         assertEquals(0, mockingDetails(foo).getInvocations().size());
88         assertEquals("[mock.simpleMethod(10);, mock.otherMethod();]", mockingDetails(mock).getInvocations().toString());
89     }
90 
91     @Test
manipulating_invocations_is_safe()92     public void manipulating_invocations_is_safe() {
93         mock.simpleMethod();
94 
95         //when we manipulate the invocations
96         mockingDetails(mock).getInvocations().clear();
97 
98         //then we didn't actually changed the invocations
99         assertEquals(1, mockingDetails(mock).getInvocations().size());
100     }
101 
102     @Test
provides_mock_creation_settings()103     public void provides_mock_creation_settings() {
104         //smoke test some creation settings
105         assertEquals(Foo.class, mockingDetails(foo).getMockCreationSettings().getTypeToMock());
106         assertEquals(Bar.class, mockingDetails(bar).getMockCreationSettings().getTypeToMock());
107         assertEquals(0, mockingDetails(mock).getMockCreationSettings().getExtraInterfaces().size());
108     }
109 
110     @Test(expected = NotAMockException.class)
fails_when_getting_creation_settings_for_incorrect_input()111     public void fails_when_getting_creation_settings_for_incorrect_input() {
112         mockingDetails(null).getMockCreationSettings();
113     }
114 
115     @Test
fails_when_getting_invocations_when_null()116     public void fails_when_getting_invocations_when_null() {
117         try {
118             //when
119             mockingDetails(null).getInvocations();
120             //then
121             fail();
122         } catch (NotAMockException e) {
123             assertEquals("Argument passed to Mockito.mockingDetails() should be a mock, but is null!", e.getMessage());
124         }
125     }
126 
127     @Test
fails_when_getting_invocations_when_not_mock()128     public void fails_when_getting_invocations_when_not_mock() {
129         try {
130             //when
131             mockingDetails(new Object()).getInvocations();
132             //then
133             fail();
134         } catch (NotAMockException e) {
135             assertEquals("Argument passed to Mockito.mockingDetails() should be a mock, but is an instance of class java.lang.Object!", e.getMessage());
136         }
137     }
138 
139     @Test
fails_when_getting_stubbings_from_non_mock()140     public void fails_when_getting_stubbings_from_non_mock() {
141         try {
142             //when
143             mockingDetails(new Object()).getStubbings();
144             //then
145             fail();
146         } catch (NotAMockException e) {
147             assertEquals("Argument passed to Mockito.mockingDetails() should be a mock, but is an instance of class java.lang.Object!", e.getMessage());
148         }
149     }
150 
151     @Test
mock_with_no_stubbings()152     public void mock_with_no_stubbings() {
153         assertTrue(mockingDetails(mock).getStubbings().isEmpty());
154     }
155 
156     @Test
provides_stubbings_of_mock_in_declaration_order()157     public void provides_stubbings_of_mock_in_declaration_order() {
158         when(mock.simpleMethod(1)).thenReturn("1");
159         when(mock.otherMethod()).thenReturn("2");
160 
161         //when
162         Collection<Stubbing> stubbings = mockingDetails(mock).getStubbings();
163 
164         //then
165         assertEquals(2, stubbings.size());
166         assertEquals("[mock.simpleMethod(1); stubbed with: [Returns: 1], mock.otherMethod(); stubbed with: [Returns: 2]]", stubbings.toString());
167     }
168 
169     @Test
manipulating_stubbings_explicitly_is_safe()170     public void manipulating_stubbings_explicitly_is_safe() {
171         when(mock.simpleMethod(1)).thenReturn("1");
172 
173         //when somebody manipulates stubbings directly
174         mockingDetails(mock).getStubbings().clear();
175 
176         //then it does not affect stubbings of the mock
177         assertEquals(1, mockingDetails(mock).getStubbings().size());
178     }
179 
180     @Test
prints_invocations()181     public void prints_invocations() throws Exception {
182         //given
183         given(mock.simpleMethod("different arg")).willReturn("foo");
184         mock.simpleMethod("arg");
185 
186         //when
187         String log = Mockito.mockingDetails(mock).printInvocations();
188 
189         //then
190         assertThat(log).containsIgnoringCase("unused");
191         assertThat(log).containsIgnoringCase("mock.simpleMethod(\"arg\")");
192         assertThat(log).containsIgnoringCase("mock.simpleMethod(\"different arg\")");
193     }
194 
195     @Test
fails_when_printin_invocations_from_non_mock()196     public void fails_when_printin_invocations_from_non_mock() {
197         try {
198             //when
199             mockingDetails(new Object()).printInvocations();
200             //then
201             fail();
202         } catch (NotAMockException e) {
203             assertEquals("Argument passed to Mockito.mockingDetails() should be a mock, but is an instance of class java.lang.Object!", e.getMessage());
204         }
205     }
206 
207     public class Foo { }
208     public interface Bar { }
209     public static class Gork { }
210 }
211