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