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 InvocationContainerImpl(MockingProgress mockingProgress, MockCreationSettings mockSettings)34 public InvocationContainerImpl(MockingProgress mockingProgress, MockCreationSettings mockSettings) { 35 this.mockingProgress = mockingProgress; 36 this.registeredInvocations = createRegisteredInvocations(mockSettings); 37 } 38 setInvocationForPotentialStubbing(InvocationMatcher invocation)39 public void setInvocationForPotentialStubbing(InvocationMatcher invocation) { 40 registeredInvocations.add(invocation.getInvocation()); 41 this.invocationForStubbing = invocation; 42 } 43 resetInvocationForPotentialStubbing(InvocationMatcher invocationMatcher)44 public void resetInvocationForPotentialStubbing(InvocationMatcher invocationMatcher) { 45 this.invocationForStubbing = invocationMatcher; 46 } 47 addAnswer(Answer answer)48 public void addAnswer(Answer answer) { 49 registeredInvocations.removeLast(); 50 addAnswer(answer, false); 51 } 52 addConsecutiveAnswer(Answer answer)53 public void addConsecutiveAnswer(Answer answer) { 54 addAnswer(answer, true); 55 } 56 addAnswer(Answer answer, boolean isConsecutive)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 answerTo(Invocation invocation)72 Object answerTo(Invocation invocation) throws Throwable { 73 return findAnswerFor(invocation).answer(invocation); 74 } 75 findAnswerFor(Invocation invocation)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 addAnswerForVoidMethod(Answer answer)90 public void addAnswerForVoidMethod(Answer answer) { 91 answersForStubbing.add(answer); 92 } 93 setAnswersForStubbing(List<Answer> answers)94 public void setAnswersForStubbing(List<Answer> answers) { 95 answersForStubbing.addAll(answers); 96 } 97 hasAnswersForStubbing()98 public boolean hasAnswersForStubbing() { 99 return !answersForStubbing.isEmpty(); 100 } 101 hasInvocationForPotentialStubbing()102 public boolean hasInvocationForPotentialStubbing() { 103 return !registeredInvocations.isEmpty(); 104 } 105 setMethodForStubbing(InvocationMatcher invocation)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 toString()116 public String toString() { 117 return "invocationForStubbing: " + invocationForStubbing; 118 } 119 getInvocations()120 public List<Invocation> getInvocations() { 121 return registeredInvocations.getAll(); 122 } 123 getStubbedInvocations()124 public List<StubbedInvocationMatcher> getStubbedInvocations() { 125 return stubbed; 126 } 127 invokedMock()128 public Object invokedMock() { 129 return invocationForStubbing.getInvocation().getMock(); 130 } 131 getInvocationForStubbing()132 public InvocationMatcher getInvocationForStubbing() { 133 return invocationForStubbing; 134 } 135 createRegisteredInvocations(MockCreationSettings mockSettings)136 private RegisteredInvocations createRegisteredInvocations(MockCreationSettings mockSettings) { 137 return mockSettings.isStubOnly() 138 ? new SingleRegisteredInvocation() 139 : new DefaultRegisteredInvocations(); 140 } 141 } 142