View Javadoc
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 }