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