1 /* 2 * Copyright (c) 2006 JMockit developers 3 * This file is subject to the terms of the MIT license (see LICENSE.txt). 4 */ 5 package mockit; 6 7 import edu.umd.cs.findbugs.annotations.NonNull; 8 import edu.umd.cs.findbugs.annotations.Nullable; 9 10 import java.util.List; 11 12 import mockit.internal.expectations.BaseVerificationPhase; 13 import mockit.internal.expectations.RecordAndReplayExecution; 14 import mockit.internal.expectations.argumentMatching.AlwaysTrueMatcher; 15 import mockit.internal.state.TestRun; 16 17 /** 18 * Used to <em>verify</em> a set of expectations on available {@linkplain Mocked mocked} types and/or instances, against 19 * the invocations which actually occurred during the test. As such, these verifications can only appear <em>after</em> 20 * having exercised the code under test. 21 * <p> 22 * An expectation verification attempts to match a number of method or constructor invocations, that we expect have 23 * occurred during the execution of code under test. By default, <em>at least one</em> matching invocation must be found 24 * for the verification to be successful; if no matching invocations are found, an assertion error is thrown. 25 * <p> 26 * Expectations are verified simply by invoking the desired method or constructor on a mocked type/instance, during the 27 * initialization of a <code>Verifications</code> object. This is done by instantiating an anonymous subclass containing 28 * an instance initialization body, or as we call it, a <em>verification block</em>: 29 * 30 * <pre>{@code 31 * // Exercise tested code. 32 * codeUnderTest.doSomething(); 33 * 34 * // Now verify that the expected invocations actually occurred (in any order). 35 * new Verifications() {{ 36 * <strong>mock1</strong>.expectedMethod(anyInt); 37 * <strong>mock2</strong>.anotherExpectedMethod(1, "test"); times = 2; 38 * }}; 39 * }</pre> 40 * 41 * The relative order between the invocations that match two or more verifications is not taken into consideration; when 42 * that is desired, the {@link VerificationsInOrder} class should be used instead. 43 * <p> 44 * Not all invocations that occurred during the execution of code under test need to be explicitly verified in a 45 * verification block. If that is desired, we can make sure that <em>all</em> such invocations are verified, by using 46 * the {@link FullVerifications} class. 47 * 48 * @see #Verifications() 49 * @see #withCapture() 50 * @see Expectations 51 * @see <a href="http://jmockit.github.io/tutorial/Mocking.html#verification" target="tutorial">Tutorial</a> 52 */ 53 public class Verifications extends Invocations { 54 /** 55 * Begins a set of unordered expectation verifications, on the available mocked types and/or mocked instances. Such 56 * verifications are meant to be executed <em>after</em> the call to code under test has been made. 57 */ 58 protected Verifications() { 59 this(false, (Object[]) null); 60 } 61 62 /** 63 * Instantiates a new verifications. 64 * 65 * @param inOrder 66 * the in order 67 * @param mockedTypesAndInstancesToVerify 68 * the mocked types and instances to verify 69 */ 70 Verifications(boolean inOrder, @Nullable Object... mockedTypesAndInstancesToVerify) { 71 RecordAndReplayExecution instance = TestRun.getRecordAndReplayForVerifications(); 72 currentPhase = instance.startVerifications(inOrder, mockedTypesAndInstancesToVerify); 73 } 74 75 /** 76 * Captures the argument value passed into the associated expectation parameter, for a matching invocation that 77 * occurred when the tested code was exercised. This method should be used in a local variable assignment expression 78 * inside a verification block. For example: 79 * 80 * <pre>{@code 81 * codeUnderTest.doSomething(); 82 * 83 * new Verifications() {{ 84 * String <strong>name</strong>; 85 * int <strong>age</strong>; 86 * personDAOMock.create(<strong>age</strong> = <em>withCapture()</em>, <strong>name</strong> = <em>withCapture()</em>); 87 * assertFalse(<strong>name</strong>.isEmpty()); 88 * assertTrue(<strong>age</strong> >= 18); 89 * }}; 90 * }</pre> 91 * 92 * If there is more than one matching invocation, then only the last one to have occurred is considered. Apart from 93 * capturing received argument values, this method has the same effect as the {@link #any} argument matcher. 94 * <p> 95 * When an argument matcher is used for a regular (ie, non-varargs) parameter in a call to a mocked 96 * method/constructor, it's <em>not</em> necessary to also use matchers for the other parameters. So, it's valid to 97 * mix the use of matchers with given values. Arguments given as literals, local variables, or fields, will be 98 * implicitly matched as if {@link #withEqual(Object)} had been used. In the special case of a varargs method, 99 * however, this flexibility is not available: if a matcher is used for any regular parameter, or for any element in 100 * the varargs array, then a matcher <em>must</em> be used for every other parameter and varargs element. 101 * 102 * @param <T> 103 * the generic type 104 * 105 * @return the captured argument value 106 * 107 * @see #withCapture(List) 108 * @see #withCapture(Object) 109 * @see <a href="http://jmockit.github.io/tutorial/Mocking.html#withCapture" target="tutorial">Tutorial</a> 110 */ 111 @Nullable 112 protected final <T> T withCapture() { 113 currentPhase.addArgMatcher(AlwaysTrueMatcher.ANY_VALUE); 114 return null; 115 } 116 117 /** 118 * Captures new instances of type <code>T</code> that were created by the code under test. Said instances are only 119 * those which were created through constructor invocations matching the constructor verification that was passed as 120 * argument in a call to this method. For example: 121 * 122 * <pre>{@code 123 * codeUnderTest.doSomething(); 124 * 125 * new Verifications() {{ 126 * <strong>List<Person> newPersons = withCapture(new Person());</strong> 127 * Person newPerson = newPersons.get(0); 128 * 129 * Person personCreated; 130 * personDAOMock.create(personCreated = withCapture()); 131 * 132 * assertSame(newPerson, personCreated); 133 * }}; 134 * }</pre> 135 * 136 * Note this is not meant be used as an argument matcher. 137 * 138 * @param <T> 139 * the generic type 140 * @param constructorVerification 141 * a new instance of the desired mocked class, created through a regular constructor verification 142 * 143 * @return a list with the (zero, one, or more) captured new instances that match the verified constructor 144 * invocation 145 * 146 * @see #withCapture() 147 * @see #withCapture(List) 148 * @see <a href="http://jmockit.github.io/tutorial/Mocking.html#withCapture" target="tutorial">Tutorial</a> 149 */ 150 @NonNull 151 protected final <T> List<T> withCapture(@NonNull T constructorVerification) { 152 return ((BaseVerificationPhase) currentPhase).getNewInstancesMatchingVerifiedConstructorInvocation(); 153 } 154 }