Home | History | Annotate | Download | only in stubbing
      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.stubbing;
      6 
      7 import org.mockito.internal.invocation.InvocationMatcher;
      8 import org.mockito.internal.invocation.StubInfoImpl;
      9 import org.mockito.internal.progress.MockingProgress;
     10 import org.mockito.internal.stubbing.answers.AnswersValidator;
     11 import org.mockito.internal.verification.DefaultRegisteredInvocations;
     12 import org.mockito.internal.verification.RegisteredInvocations;
     13 import org.mockito.internal.verification.SingleRegisteredInvocation;
     14 import org.mockito.invocation.Invocation;
     15 import org.mockito.mock.MockCreationSettings;
     16 import org.mockito.stubbing.Answer;
     17 
     18 import java.io.Serializable;
     19 import java.util.ArrayList;
     20 import java.util.LinkedList;
     21 import java.util.List;
     22 
     23 @SuppressWarnings("unchecked")
     24 public class InvocationContainerImpl implements InvocationContainer, Serializable {
     25 
     26     private static final long serialVersionUID = -5334301962749537177L;
     27     private final LinkedList<StubbedInvocationMatcher> stubbed = new LinkedList<StubbedInvocationMatcher>();
     28     private final MockingProgress mockingProgress;
     29     private final List<Answer> answersForStubbing = new ArrayList<Answer>();
     30     private final RegisteredInvocations registeredInvocations;
     31 
     32     private InvocationMatcher invocationForStubbing;
     33 
     34     public InvocationContainerImpl(MockingProgress mockingProgress, MockCreationSettings mockSettings) {
     35         this.mockingProgress = mockingProgress;
     36         this.registeredInvocations = createRegisteredInvocations(mockSettings);
     37     }
     38 
     39     public void setInvocationForPotentialStubbing(InvocationMatcher invocation) {
     40         registeredInvocations.add(invocation.getInvocation());
     41         this.invocationForStubbing = invocation;
     42     }
     43 
     44     public void resetInvocationForPotentialStubbing(InvocationMatcher invocationMatcher) {
     45         this.invocationForStubbing = invocationMatcher;
     46     }
     47 
     48     public void addAnswer(Answer answer) {
     49         registeredInvocations.removeLast();
     50         addAnswer(answer, false);
     51     }
     52 
     53     public void addConsecutiveAnswer(Answer answer) {
     54         addAnswer(answer, true);
     55     }
     56 
     57     public void addAnswer(Answer answer, boolean isConsecutive) {
     58         Invocation invocation = invocationForStubbing.getInvocation();
     59         mockingProgress.stubbingCompleted(invocation);
     60         AnswersValidator answersValidator = new AnswersValidator();
     61         answersValidator.validate(answer, invocation);
     62 
     63         synchronized (stubbed) {
     64             if (isConsecutive) {
     65                 stubbed.getFirst().addAnswer(answer);
     66             } else {
     67                 stubbed.addFirst(new StubbedInvocationMatcher(invocationForStubbing, answer));
     68             }
     69         }
     70     }
     71 
     72     Object answerTo(Invocation invocation) throws Throwable {
     73         return findAnswerFor(invocation).answer(invocation);
     74     }
     75 
     76     public StubbedInvocationMatcher findAnswerFor(Invocation invocation) {
     77         synchronized (stubbed) {
     78             for (StubbedInvocationMatcher s : stubbed) {
     79                 if (s.matches(invocation)) {
     80                     s.markStubUsed(invocation);
     81                     invocation.markStubbed(new StubInfoImpl(s));
     82                     return s;
     83                 }
     84             }
     85         }
     86 
     87         return null;
     88     }
     89 
     90     public void addAnswerForVoidMethod(Answer answer) {
     91         answersForStubbing.add(answer);
     92     }
     93 
     94     public void setAnswersForStubbing(List<Answer> answers) {
     95         answersForStubbing.addAll(answers);
     96     }
     97 
     98     public boolean hasAnswersForStubbing() {
     99         return !answersForStubbing.isEmpty();
    100     }
    101 
    102     public boolean hasInvocationForPotentialStubbing() {
    103         return !registeredInvocations.isEmpty();
    104     }
    105 
    106     public void setMethodForStubbing(InvocationMatcher invocation) {
    107         invocationForStubbing = invocation;
    108         assert hasAnswersForStubbing();
    109         for (int i = 0; i < answersForStubbing.size(); i++) {
    110             addAnswer(answersForStubbing.get(i), i != 0);
    111         }
    112         answersForStubbing.clear();
    113     }
    114 
    115     @Override
    116     public String toString() {
    117         return "invocationForStubbing: " + invocationForStubbing;
    118     }
    119 
    120     public List<Invocation> getInvocations() {
    121         return registeredInvocations.getAll();
    122     }
    123 
    124     public List<StubbedInvocationMatcher> getStubbedInvocations() {
    125         return stubbed;
    126     }
    127 
    128     public Object invokedMock() {
    129         return invocationForStubbing.getInvocation().getMock();
    130     }
    131 
    132     public InvocationMatcher getInvocationForStubbing() {
    133     	return invocationForStubbing;
    134     }
    135 
    136     private RegisteredInvocations createRegisteredInvocations(MockCreationSettings mockSettings) {
    137         return mockSettings.isStubOnly()
    138           ? new SingleRegisteredInvocation()
    139           : new DefaultRegisteredInvocations();
    140     }
    141 }
    142