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