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 org.mockito.InOrder; 8 import org.mockito.MockSettings; 9 import org.mockito.MockingDetails; 10 import org.mockito.exceptions.misusing.NotAMockException; 11 import org.mockito.internal.creation.MockSettingsImpl; 12 import org.mockito.internal.invocation.finder.VerifiableInvocationsFinder; 13 import org.mockito.internal.listeners.VerificationStartedNotifier; 14 import org.mockito.internal.progress.MockingProgress; 15 import org.mockito.internal.stubbing.InvocationContainerImpl; 16 import org.mockito.internal.stubbing.OngoingStubbingImpl; 17 import org.mockito.internal.stubbing.StubberImpl; 18 import org.mockito.internal.util.DefaultMockingDetails; 19 import org.mockito.internal.verification.MockAwareVerificationMode; 20 import org.mockito.internal.verification.VerificationDataImpl; 21 import org.mockito.internal.verification.VerificationModeFactory; 22 import org.mockito.internal.verification.api.InOrderContext; 23 import org.mockito.internal.verification.api.VerificationDataInOrder; 24 import org.mockito.internal.verification.api.VerificationDataInOrderImpl; 25 import org.mockito.invocation.Invocation; 26 import org.mockito.invocation.MockHandler; 27 import org.mockito.mock.MockCreationSettings; 28 import org.mockito.stubbing.OngoingStubbing; 29 import org.mockito.stubbing.Stubber; 30 import org.mockito.verification.VerificationMode; 31 32 import java.util.Arrays; 33 import java.util.List; 34 35 import static org.mockito.internal.exceptions.Reporter.missingMethodInvocation; 36 import static org.mockito.internal.exceptions.Reporter.mocksHaveToBePassedToVerifyNoMoreInteractions; 37 import static org.mockito.internal.exceptions.Reporter.mocksHaveToBePassedWhenCreatingInOrder; 38 import static org.mockito.internal.exceptions.Reporter.notAMockPassedToVerify; 39 import static org.mockito.internal.exceptions.Reporter.notAMockPassedToVerifyNoMoreInteractions; 40 import static org.mockito.internal.exceptions.Reporter.notAMockPassedWhenCreatingInOrder; 41 import static org.mockito.internal.exceptions.Reporter.nullPassedToVerify; 42 import static org.mockito.internal.exceptions.Reporter.nullPassedToVerifyNoMoreInteractions; 43 import static org.mockito.internal.exceptions.Reporter.nullPassedWhenCreatingInOrder; 44 import static org.mockito.internal.progress.ThreadSafeMockingProgress.mockingProgress; 45 import static org.mockito.internal.util.MockUtil.createMock; 46 import static org.mockito.internal.util.MockUtil.getInvocationContainer; 47 import static org.mockito.internal.util.MockUtil.isMock; 48 import static org.mockito.internal.util.MockUtil.resetMock; 49 import static org.mockito.internal.util.MockUtil.typeMockabilityOf; 50 import static org.mockito.internal.verification.VerificationModeFactory.noMoreInteractions; 51 52 @SuppressWarnings("unchecked") 53 public class MockitoCore { 54 isTypeMockable(Class<?> typeToMock)55 public boolean isTypeMockable(Class<?> typeToMock) { 56 return typeMockabilityOf(typeToMock).mockable(); 57 } 58 mock(Class<T> typeToMock, MockSettings settings)59 public <T> T mock(Class<T> typeToMock, MockSettings settings) { 60 if (!MockSettingsImpl.class.isInstance(settings)) { 61 throw new IllegalArgumentException("Unexpected implementation of '" + settings.getClass().getCanonicalName() + "'\n" + "At the moment, you cannot provide your own implementations of that class."); 62 } 63 MockSettingsImpl impl = MockSettingsImpl.class.cast(settings); 64 MockCreationSettings<T> creationSettings = impl.build(typeToMock); 65 T mock = createMock(creationSettings); 66 mockingProgress().mockingStarted(mock, creationSettings); 67 return mock; 68 } 69 when(T methodCall)70 public <T> OngoingStubbing<T> when(T methodCall) { 71 MockingProgress mockingProgress = mockingProgress(); 72 mockingProgress.stubbingStarted(); 73 @SuppressWarnings("unchecked") 74 OngoingStubbing<T> stubbing = (OngoingStubbing<T>) mockingProgress.pullOngoingStubbing(); 75 if (stubbing == null) { 76 mockingProgress.reset(); 77 throw missingMethodInvocation(); 78 } 79 return stubbing; 80 } 81 verify(T mock, VerificationMode mode)82 public <T> T verify(T mock, VerificationMode mode) { 83 if (mock == null) { 84 throw nullPassedToVerify(); 85 } 86 MockingDetails mockingDetails = mockingDetails(mock); 87 if (!mockingDetails.isMock()) { 88 throw notAMockPassedToVerify(mock.getClass()); 89 } 90 MockHandler handler = mockingDetails.getMockHandler(); 91 92 mock = (T) VerificationStartedNotifier.notifyVerificationStarted( 93 handler.getMockSettings().getVerificationStartedListeners(), mockingDetails); 94 95 MockingProgress mockingProgress = mockingProgress(); 96 VerificationMode actualMode = mockingProgress.maybeVerifyLazily(mode); 97 mockingProgress.verificationStarted(new MockAwareVerificationMode(mock, actualMode, mockingProgress.verificationListeners())); 98 return mock; 99 } 100 reset(T... mocks)101 public <T> void reset(T... mocks) { 102 MockingProgress mockingProgress = mockingProgress(); 103 mockingProgress.validateState(); 104 mockingProgress.reset(); 105 mockingProgress.resetOngoingStubbing(); 106 107 for (T m : mocks) { 108 resetMock(m); 109 } 110 } 111 clearInvocations(T... mocks)112 public <T> void clearInvocations(T... mocks) { 113 MockingProgress mockingProgress = mockingProgress(); 114 mockingProgress.validateState(); 115 mockingProgress.reset(); 116 mockingProgress.resetOngoingStubbing(); 117 118 for (T m : mocks) { 119 getInvocationContainer(m).clearInvocations(); 120 } 121 } 122 verifyNoMoreInteractions(Object... mocks)123 public void verifyNoMoreInteractions(Object... mocks) { 124 assertMocksNotEmpty(mocks); 125 mockingProgress().validateState(); 126 for (Object mock : mocks) { 127 try { 128 if (mock == null) { 129 throw nullPassedToVerifyNoMoreInteractions(); 130 } 131 InvocationContainerImpl invocations = getInvocationContainer(mock); 132 VerificationDataImpl data = new VerificationDataImpl(invocations, null); 133 noMoreInteractions().verify(data); 134 } catch (NotAMockException e) { 135 throw notAMockPassedToVerifyNoMoreInteractions(); 136 } 137 } 138 } 139 verifyNoMoreInteractionsInOrder(List<Object> mocks, InOrderContext inOrderContext)140 public void verifyNoMoreInteractionsInOrder(List<Object> mocks, InOrderContext inOrderContext) { 141 mockingProgress().validateState(); 142 VerificationDataInOrder data = new VerificationDataInOrderImpl(inOrderContext, VerifiableInvocationsFinder.find(mocks), null); 143 VerificationModeFactory.noMoreInteractions().verifyInOrder(data); 144 } 145 assertMocksNotEmpty(Object[] mocks)146 private void assertMocksNotEmpty(Object[] mocks) { 147 if (mocks == null || mocks.length == 0) { 148 throw mocksHaveToBePassedToVerifyNoMoreInteractions(); 149 } 150 } 151 inOrder(Object... mocks)152 public InOrder inOrder(Object... mocks) { 153 if (mocks == null || mocks.length == 0) { 154 throw mocksHaveToBePassedWhenCreatingInOrder(); 155 } 156 for (Object mock : mocks) { 157 if (mock == null) { 158 throw nullPassedWhenCreatingInOrder(); 159 } 160 if (!isMock(mock)) { 161 throw notAMockPassedWhenCreatingInOrder(); 162 } 163 } 164 return new InOrderImpl(Arrays.asList(mocks)); 165 } 166 stubber()167 public Stubber stubber() { 168 MockingProgress mockingProgress = mockingProgress(); 169 mockingProgress.stubbingStarted(); 170 mockingProgress.resetOngoingStubbing(); 171 return new StubberImpl(); 172 } 173 validateMockitoUsage()174 public void validateMockitoUsage() { 175 mockingProgress().validateState(); 176 } 177 178 /** 179 * For testing purposes only. Is not the part of main API. 180 * 181 * @return last invocation 182 */ getLastInvocation()183 public Invocation getLastInvocation() { 184 OngoingStubbingImpl ongoingStubbing = ((OngoingStubbingImpl) mockingProgress().pullOngoingStubbing()); 185 List<Invocation> allInvocations = ongoingStubbing.getRegisteredInvocations(); 186 return allInvocations.get(allInvocations.size() - 1); 187 } 188 ignoreStubs(Object... mocks)189 public Object[] ignoreStubs(Object... mocks) { 190 for (Object m : mocks) { 191 InvocationContainerImpl container = getInvocationContainer(m); 192 List<Invocation> ins = container.getInvocations(); 193 for (Invocation in : ins) { 194 if (in.stubInfo() != null) { 195 in.ignoreForVerification(); 196 } 197 } 198 } 199 return mocks; 200 } 201 mockingDetails(Object toInspect)202 public MockingDetails mockingDetails(Object toInspect) { 203 return new DefaultMockingDetails(toInspect); 204 } 205 } 206