• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2007 Mockito contributors
3  * This program is made available under the terms of the MIT License.
4  */
5 package org.mockito.internal;
6 
7 import static org.mockito.internal.exceptions.Reporter.missingMethodInvocation;
8 import static org.mockito.internal.exceptions.Reporter.mocksHaveToBePassedToVerifyNoMoreInteractions;
9 import static org.mockito.internal.exceptions.Reporter.mocksHaveToBePassedWhenCreatingInOrder;
10 import static org.mockito.internal.exceptions.Reporter.notAMockPassedToVerify;
11 import static org.mockito.internal.exceptions.Reporter.notAMockPassedToVerifyNoMoreInteractions;
12 import static org.mockito.internal.exceptions.Reporter.notAMockPassedWhenCreatingInOrder;
13 import static org.mockito.internal.exceptions.Reporter.nullPassedToVerify;
14 import static org.mockito.internal.exceptions.Reporter.nullPassedToVerifyNoMoreInteractions;
15 import static org.mockito.internal.exceptions.Reporter.nullPassedWhenCreatingInOrder;
16 import static org.mockito.internal.exceptions.Reporter.stubPassedToVerify;
17 import static org.mockito.internal.progress.ThreadSafeMockingProgress.mockingProgress;
18 import static org.mockito.internal.util.MockUtil.createConstructionMock;
19 import static org.mockito.internal.util.MockUtil.createMock;
20 import static org.mockito.internal.util.MockUtil.createStaticMock;
21 import static org.mockito.internal.util.MockUtil.getInvocationContainer;
22 import static org.mockito.internal.util.MockUtil.getMockHandler;
23 import static org.mockito.internal.util.MockUtil.isMock;
24 import static org.mockito.internal.util.MockUtil.resetMock;
25 import static org.mockito.internal.util.MockUtil.typeMockabilityOf;
26 import static org.mockito.internal.verification.VerificationModeFactory.noInteractions;
27 import static org.mockito.internal.verification.VerificationModeFactory.noMoreInteractions;
28 
29 import java.util.Arrays;
30 import java.util.Collections;
31 import java.util.HashSet;
32 import java.util.List;
33 import java.util.Set;
34 
35 import org.mockito.InOrder;
36 import org.mockito.MockSettings;
37 import org.mockito.MockedConstruction;
38 import org.mockito.MockedStatic;
39 import org.mockito.MockingDetails;
40 import org.mockito.exceptions.misusing.DoNotMockException;
41 import org.mockito.exceptions.misusing.NotAMockException;
42 import org.mockito.internal.configuration.plugins.Plugins;
43 import org.mockito.internal.creation.MockSettingsImpl;
44 import org.mockito.internal.invocation.finder.VerifiableInvocationsFinder;
45 import org.mockito.internal.listeners.VerificationStartedNotifier;
46 import org.mockito.internal.progress.MockingProgress;
47 import org.mockito.internal.stubbing.DefaultLenientStubber;
48 import org.mockito.internal.stubbing.InvocationContainerImpl;
49 import org.mockito.internal.stubbing.OngoingStubbingImpl;
50 import org.mockito.internal.stubbing.StubberImpl;
51 import org.mockito.internal.util.DefaultMockingDetails;
52 import org.mockito.internal.util.MockUtil;
53 import org.mockito.internal.verification.MockAwareVerificationMode;
54 import org.mockito.internal.verification.VerificationDataImpl;
55 import org.mockito.internal.verification.VerificationModeFactory;
56 import org.mockito.internal.verification.api.InOrderContext;
57 import org.mockito.internal.verification.api.VerificationDataInOrder;
58 import org.mockito.internal.verification.api.VerificationDataInOrderImpl;
59 import org.mockito.invocation.Invocation;
60 import org.mockito.invocation.MockHandler;
61 import org.mockito.mock.MockCreationSettings;
62 import org.mockito.plugins.DoNotMockEnforcer;
63 import org.mockito.plugins.MockMaker;
64 import org.mockito.quality.Strictness;
65 import org.mockito.stubbing.LenientStubber;
66 import org.mockito.stubbing.OngoingStubbing;
67 import org.mockito.stubbing.Stubber;
68 import org.mockito.verification.VerificationMode;
69 
70 import java.util.Arrays;
71 import java.util.List;
72 import java.util.function.Function;
73 
74 @SuppressWarnings("unchecked")
75 public class MockitoCore {
76 
77     private static final DoNotMockEnforcer DO_NOT_MOCK_ENFORCER = Plugins.getDoNotMockEnforcer();
78     private static final Set<Class<?>> MOCKABLE_CLASSES =
79             Collections.synchronizedSet(new HashSet<>());
80 
isTypeMockable(Class<?> typeToMock)81     public boolean isTypeMockable(Class<?> typeToMock) {
82         return typeMockabilityOf(typeToMock).mockable();
83     }
84 
mock(Class<T> typeToMock, MockSettings settings)85     public <T> T mock(Class<T> typeToMock, MockSettings settings) {
86         if (!(settings instanceof MockSettingsImpl)) {
87             throw new IllegalArgumentException(
88                     "Unexpected implementation of '"
89                             + settings.getClass().getCanonicalName()
90                             + "'\n"
91                             + "At the moment, you cannot provide your own implementations of that class.");
92         }
93         MockSettingsImpl impl = (MockSettingsImpl) settings;
94         MockCreationSettings<T> creationSettings = impl.build(typeToMock);
95         checkDoNotMockAnnotation(creationSettings.getTypeToMock(), creationSettings);
96         T mock = createMock(creationSettings);
97         mockingProgress().mockingStarted(mock, creationSettings);
98         return mock;
99     }
100 
checkDoNotMockAnnotation( Class<?> typeToMock, MockCreationSettings<?> creationSettings)101     private void checkDoNotMockAnnotation(
102             Class<?> typeToMock, MockCreationSettings<?> creationSettings) {
103         checkDoNotMockAnnotationForType(typeToMock);
104         for (Class<?> aClass : creationSettings.getExtraInterfaces()) {
105             checkDoNotMockAnnotationForType(aClass);
106         }
107     }
108 
checkDoNotMockAnnotationForType(Class<?> type)109     private static void checkDoNotMockAnnotationForType(Class<?> type) {
110         // Object and interfaces do not have a super class
111         if (type == null) {
112             return;
113         }
114 
115         if (MOCKABLE_CLASSES.contains(type)) {
116             return;
117         }
118 
119         String warning = DO_NOT_MOCK_ENFORCER.checkTypeForDoNotMockViolation(type);
120         if (warning != null) {
121             throw new DoNotMockException(warning);
122         }
123 
124         checkDoNotMockAnnotationForType(type.getSuperclass());
125         for (Class<?> aClass : type.getInterfaces()) {
126             checkDoNotMockAnnotationForType(aClass);
127         }
128 
129         MOCKABLE_CLASSES.add(type);
130     }
131 
mockStatic(Class<T> classToMock, MockSettings settings)132     public <T> MockedStatic<T> mockStatic(Class<T> classToMock, MockSettings settings) {
133         if (!MockSettingsImpl.class.isInstance(settings)) {
134             throw new IllegalArgumentException(
135                     "Unexpected implementation of '"
136                             + settings.getClass().getCanonicalName()
137                             + "'\n"
138                             + "At the moment, you cannot provide your own implementations of that class.");
139         }
140         MockSettingsImpl impl = MockSettingsImpl.class.cast(settings);
141         MockCreationSettings<T> creationSettings = impl.buildStatic(classToMock);
142         MockMaker.StaticMockControl<T> control = createStaticMock(classToMock, creationSettings);
143         control.enable();
144         mockingProgress().mockingStarted(classToMock, creationSettings);
145         return new MockedStaticImpl<>(control);
146     }
147 
mockConstruction( Class<T> typeToMock, Function<MockedConstruction.Context, ? extends MockSettings> settingsFactory, MockedConstruction.MockInitializer<T> mockInitializer)148     public <T> MockedConstruction<T> mockConstruction(
149             Class<T> typeToMock,
150             Function<MockedConstruction.Context, ? extends MockSettings> settingsFactory,
151             MockedConstruction.MockInitializer<T> mockInitializer) {
152         Function<MockedConstruction.Context, MockCreationSettings<T>> creationSettings =
153                 context -> {
154                     MockSettings value = settingsFactory.apply(context);
155                     if (!MockSettingsImpl.class.isInstance(value)) {
156                         throw new IllegalArgumentException(
157                                 "Unexpected implementation of '"
158                                         + value.getClass().getCanonicalName()
159                                         + "'\n"
160                                         + "At the moment, you cannot provide your own implementations of that class.");
161                     }
162                     MockSettingsImpl impl = MockSettingsImpl.class.cast(value);
163                     return impl.build(typeToMock);
164                 };
165         MockMaker.ConstructionMockControl<T> control =
166                 createConstructionMock(typeToMock, creationSettings, mockInitializer);
167         control.enable();
168         return new MockedConstructionImpl<>(control);
169     }
170 
when(T methodCall)171     public <T> OngoingStubbing<T> when(T methodCall) {
172         MockingProgress mockingProgress = mockingProgress();
173         mockingProgress.stubbingStarted();
174         @SuppressWarnings("unchecked")
175         OngoingStubbing<T> stubbing = (OngoingStubbing<T>) mockingProgress.pullOngoingStubbing();
176         if (stubbing == null) {
177             mockingProgress.reset();
178             throw missingMethodInvocation();
179         }
180         return stubbing;
181     }
182 
verify(T mock, VerificationMode mode)183     public <T> T verify(T mock, VerificationMode mode) {
184         if (mock == null) {
185             throw nullPassedToVerify();
186         }
187         MockingDetails mockingDetails = mockingDetails(mock);
188         if (!mockingDetails.isMock()) {
189             throw notAMockPassedToVerify(mock.getClass());
190         }
191         assertNotStubOnlyMock(mock);
192         MockHandler handler = mockingDetails.getMockHandler();
193         mock =
194                 (T)
195                         VerificationStartedNotifier.notifyVerificationStarted(
196                                 handler.getMockSettings().getVerificationStartedListeners(),
197                                 mockingDetails);
198 
199         MockingProgress mockingProgress = mockingProgress();
200         VerificationMode actualMode = mockingProgress.maybeVerifyLazily(mode);
201         mockingProgress.verificationStarted(
202                 new MockAwareVerificationMode(
203                         mock, actualMode, mockingProgress.verificationListeners()));
204         return mock;
205     }
206 
reset(T... mocks)207     public <T> void reset(T... mocks) {
208         MockingProgress mockingProgress = mockingProgress();
209         mockingProgress.validateState();
210         mockingProgress.reset();
211         mockingProgress.resetOngoingStubbing();
212 
213         for (T m : mocks) {
214             resetMock(m);
215         }
216     }
217 
clearInvocations(T... mocks)218     public <T> void clearInvocations(T... mocks) {
219         MockingProgress mockingProgress = mockingProgress();
220         mockingProgress.validateState();
221         mockingProgress.reset();
222         mockingProgress.resetOngoingStubbing();
223 
224         for (T m : mocks) {
225             getInvocationContainer(m).clearInvocations();
226         }
227     }
228 
verifyNoMoreInteractions(Object... mocks)229     public void verifyNoMoreInteractions(Object... mocks) {
230         assertMocksNotEmpty(mocks);
231         mockingProgress().validateState();
232         for (Object mock : mocks) {
233             try {
234                 if (mock == null) {
235                     throw nullPassedToVerifyNoMoreInteractions();
236                 }
237                 InvocationContainerImpl invocations = getInvocationContainer(mock);
238                 assertNotStubOnlyMock(mock);
239                 VerificationDataImpl data = new VerificationDataImpl(invocations, null);
240                 noMoreInteractions().verify(data);
241             } catch (NotAMockException e) {
242                 throw notAMockPassedToVerifyNoMoreInteractions();
243             }
244         }
245     }
246 
verifyNoInteractions(Object... mocks)247     public void verifyNoInteractions(Object... mocks) {
248         assertMocksNotEmpty(mocks);
249         mockingProgress().validateState();
250         for (Object mock : mocks) {
251             try {
252                 if (mock == null) {
253                     throw nullPassedToVerifyNoMoreInteractions();
254                 }
255                 InvocationContainerImpl invocations = getInvocationContainer(mock);
256                 assertNotStubOnlyMock(mock);
257                 VerificationDataImpl data = new VerificationDataImpl(invocations, null);
258                 noInteractions().verify(data);
259             } catch (NotAMockException e) {
260                 throw notAMockPassedToVerifyNoMoreInteractions();
261             }
262         }
263     }
264 
verifyNoMoreInteractionsInOrder(List<Object> mocks, InOrderContext inOrderContext)265     public void verifyNoMoreInteractionsInOrder(List<Object> mocks, InOrderContext inOrderContext) {
266         mockingProgress().validateState();
267         VerificationDataInOrder data =
268                 new VerificationDataInOrderImpl(
269                         inOrderContext, VerifiableInvocationsFinder.find(mocks), null);
270         VerificationModeFactory.noMoreInteractions().verifyInOrder(data);
271     }
272 
assertMocksNotEmpty(Object[] mocks)273     private void assertMocksNotEmpty(Object[] mocks) {
274         if (mocks == null || mocks.length == 0) {
275             throw mocksHaveToBePassedToVerifyNoMoreInteractions();
276         }
277     }
278 
assertNotStubOnlyMock(Object mock)279     private void assertNotStubOnlyMock(Object mock) {
280         if (getMockHandler(mock).getMockSettings().isStubOnly()) {
281             throw stubPassedToVerify(mock);
282         }
283     }
284 
inOrder(Object... mocks)285     public InOrder inOrder(Object... mocks) {
286         if (mocks == null || mocks.length == 0) {
287             throw mocksHaveToBePassedWhenCreatingInOrder();
288         }
289         for (Object mock : mocks) {
290             if (mock == null) {
291                 throw nullPassedWhenCreatingInOrder();
292             }
293             if (!isMock(mock)) {
294                 throw notAMockPassedWhenCreatingInOrder();
295             }
296             assertNotStubOnlyMock(mock);
297         }
298         return new InOrderImpl(Arrays.asList(mocks));
299     }
300 
stubber()301     public Stubber stubber() {
302         return stubber(null);
303     }
304 
stubber(Strictness strictness)305     public Stubber stubber(Strictness strictness) {
306         MockingProgress mockingProgress = mockingProgress();
307         mockingProgress.stubbingStarted();
308         mockingProgress.resetOngoingStubbing();
309         return new StubberImpl(strictness);
310     }
311 
validateMockitoUsage()312     public void validateMockitoUsage() {
313         mockingProgress().validateState();
314     }
315 
316     /**
317      * For testing purposes only. Is not the part of main API.
318      *
319      * @return last invocation
320      */
getLastInvocation()321     public Invocation getLastInvocation() {
322         OngoingStubbingImpl ongoingStubbing =
323                 ((OngoingStubbingImpl) mockingProgress().pullOngoingStubbing());
324         List<Invocation> allInvocations = ongoingStubbing.getRegisteredInvocations();
325         return allInvocations.get(allInvocations.size() - 1);
326     }
327 
ignoreStubs(Object... mocks)328     public Object[] ignoreStubs(Object... mocks) {
329         for (Object m : mocks) {
330             InvocationContainerImpl container = getInvocationContainer(m);
331             List<Invocation> ins = container.getInvocations();
332             for (Invocation in : ins) {
333                 if (in.stubInfo() != null) {
334                     in.ignoreForVerification();
335                 }
336             }
337         }
338         return mocks;
339     }
340 
mockingDetails(Object toInspect)341     public MockingDetails mockingDetails(Object toInspect) {
342         return new DefaultMockingDetails(toInspect);
343     }
344 
lenient()345     public LenientStubber lenient() {
346         return new DefaultLenientStubber();
347     }
348 
clearAllCaches()349     public void clearAllCaches() {
350         MockUtil.clearAllCaches();
351     }
352 }
353