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