mockit.Verifications Maven / Gradle / Ivy
Show all versions of jmockit Show documentation
/*
* Copyright (c) 2006 JMockit developers
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.util.List;
import mockit.internal.expectations.BaseVerificationPhase;
import mockit.internal.expectations.RecordAndReplayExecution;
import mockit.internal.expectations.argumentMatching.AlwaysTrueMatcher;
import mockit.internal.state.TestRun;
/**
* Used to verify a set of expectations on available {@linkplain Mocked mocked} types and/or instances, against
* the invocations which actually occurred during the test. As such, these verifications can only appear after
* having exercised the code under test.
*
* An expectation verification attempts to match a number of method or constructor invocations, that we expect have
* occurred during the execution of code under test. By default, at least one matching invocation must be found
* for the verification to be successful; if no matching invocations are found, an assertion error is thrown.
*
* Expectations are verified simply by invoking the desired method or constructor on a mocked type/instance, during the
* initialization of a Verifications
object. This is done by instantiating an anonymous subclass containing
* an instance initialization body, or as we call it, a verification block:
*
*
{@code
* // Exercise tested code.
* codeUnderTest.doSomething();
*
* // Now verify that the expected invocations actually occurred (in any order).
* new Verifications() {{
* mock1.expectedMethod(anyInt);
* mock2.anotherExpectedMethod(1, "test"); times = 2;
* }};
* }
*
* The relative order between the invocations that match two or more verifications is not taken into consideration; when
* that is desired, the {@link VerificationsInOrder} class should be used instead.
*
* Not all invocations that occurred during the execution of code under test need to be explicitly verified in a
* verification block. If that is desired, we can make sure that all such invocations are verified, by using
* the {@link FullVerifications} class.
*
* @see #Verifications()
* @see #withCapture()
* @see Expectations
* @see Tutorial
*/
public class Verifications extends Invocations {
/**
* Begins a set of unordered expectation verifications, on the available mocked types and/or mocked instances. Such
* verifications are meant to be executed after the call to code under test has been made.
*/
protected Verifications() {
this(false, (Object[]) null);
}
/**
* Instantiates a new verifications.
*
* @param inOrder
* the in order
* @param mockedTypesAndInstancesToVerify
* the mocked types and instances to verify
*/
Verifications(boolean inOrder, @Nullable Object... mockedTypesAndInstancesToVerify) {
RecordAndReplayExecution instance = TestRun.getRecordAndReplayForVerifications();
currentPhase = instance.startVerifications(inOrder, mockedTypesAndInstancesToVerify);
}
/**
* Captures the argument value passed into the associated expectation parameter, for a matching invocation that
* occurred when the tested code was exercised. This method should be used in a local variable assignment expression
* inside a verification block. For example:
*
*
{@code
* codeUnderTest.doSomething();
*
* new Verifications() {{
* String name;
* int age;
* personDAOMock.create(age = withCapture(), name = withCapture());
* assertFalse(name.isEmpty());
* assertTrue(age >= 18);
* }};
* }
*
* If there is more than one matching invocation, then only the last one to have occurred is considered. Apart from
* capturing received argument values, this method has the same effect as the {@link #any} argument matcher.
*
* When an argument matcher is used for a regular (ie, non-varargs) parameter in a call to a mocked
* method/constructor, it's not necessary to also use matchers for the other parameters. So, it's valid to
* mix the use of matchers with given values. Arguments given as literals, local variables, or fields, will be
* implicitly matched as if {@link #withEqual(Object)} had been used. In the special case of a varargs method,
* however, this flexibility is not available: if a matcher is used for any regular parameter, or for any element in
* the varargs array, then a matcher must be used for every other parameter and varargs element.
*
* @param
* the generic type
*
* @return the captured argument value
*
* @see #withCapture(List)
* @see #withCapture(Object)
* @see Tutorial
*/
@Nullable
protected final T withCapture() {
currentPhase.addArgMatcher(AlwaysTrueMatcher.ANY_VALUE);
return null;
}
/**
* Captures new instances of type T
that were created by the code under test. Said instances are only
* those which were created through constructor invocations matching the constructor verification that was passed as
* argument in a call to this method. For example:
*
* {@code
* codeUnderTest.doSomething();
*
* new Verifications() {{
* List newPersons = withCapture(new Person());
* Person newPerson = newPersons.get(0);
*
* Person personCreated;
* personDAOMock.create(personCreated = withCapture());
*
* assertSame(newPerson, personCreated);
* }};
* }
*
* Note this is not meant be used as an argument matcher.
*
* @param
* the generic type
* @param constructorVerification
* a new instance of the desired mocked class, created through a regular constructor verification
*
* @return a list with the (zero, one, or more) captured new instances that match the verified constructor
* invocation
*
* @see #withCapture()
* @see #withCapture(List)
* @see Tutorial
*/
@NonNull
protected final List withCapture(@NonNull T constructorVerification) {
return ((BaseVerificationPhase) currentPhase).getNewInstancesMatchingVerifiedConstructorInvocation();
}
}