mockit.Invocations Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jmockit Show documentation
Show all versions of jmockit Show documentation
JMockit is a Java toolkit for automated developer testing.
It contains mocking/faking APIs and a code coverage tool, supporting both JUnit and TestNG.
The mocking APIs allow all kinds of Java code, without testability restrictions, to be tested
in isolation from selected dependencies.
/*
* Copyright (c) 2006 JMockit developers
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit;
import java.lang.reflect.*;
import java.util.*;
import java.util.regex.*;
import javax.annotation.*;
import mockit.internal.expectations.*;
import mockit.internal.expectations.argumentMatching.*;
import mockit.internal.startup.*;
import mockit.internal.util.*;
import org.hamcrest.Matcher;
/**
* Provides common API for use inside {@linkplain Expectations expectation} and {@linkplain Verifications verification}
* blocks.
*/
@SuppressWarnings("ClassWithTooManyFields")
abstract class Invocations
{
static { Startup.verifyInitialization(); }
/**
* Matches any Object reference received by a parameter of a reference type.
*
* This field can only be used as the argument value at the proper parameter position in a method/constructor
* invocation, when recording or verifying an expectation; it cannot be used anywhere else.
*
* 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.
* Any 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.
*
* Notice the use of this field will usually require a cast to the specific parameter type.
* However, if there is any other parameter for which an argument matching constraint is specified, passing the
* null reference instead will have the same effect.
*
* To match an entire varargs parameter of element type V (ie, all arguments in the array), cast it
* to the parameter type: "(V[]) any".
*
* @see #anyBoolean
* @see #anyByte
* @see #anyChar
* @see #anyDouble
* @see #anyFloat
* @see #anyInt
* @see #anyLong
* @see #anyShort
* @see #anyString
* @see Tutorial
*/
protected final Object any = null;
/**
* Matches any String value received by a parameter of this type.
*
* This field can only be used as the argument value at the proper parameter position in a method/constructor
* invocation, when recording or verifying an expectation; it cannot be used anywhere else.
*
* 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.
* Any 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.
*
* @see #anyBoolean
* @see #anyByte
* @see #anyChar
* @see #anyDouble
* @see #anyFloat
* @see #anyInt
* @see #anyLong
* @see #anyShort
* @see #any
* @see Tutorial
*/
// This is intentional: the empty string causes the compiler to not generate a field read,
// while the null reference is inconvenient with the invoke(...) methods:
protected final String anyString = new String();
/**
* Matches any long or Long value received by a parameter of that type.
*
* This field can only be used as the argument value at the proper parameter position in a method/constructor
* invocation, when recording or verifying an expectation; it cannot be used anywhere else.
*
* 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.
* Any 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.
*
* @see #anyBoolean
* @see #anyByte
* @see #anyChar
* @see #anyDouble
* @see #anyFloat
* @see #anyInt
* @see #anyShort
* @see #anyString
* @see #any
* @see Tutorial
*/
protected final Long anyLong = 0L;
/**
* Matches any int or Integer value received by a parameter of that type.
*
* This field can only be used as the argument value at the proper parameter position in a method/constructor
* invocation, when recording or verifying an expectation; it cannot be used anywhere else.
*
* 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.
* Any 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.
*
* @see #anyBoolean
* @see #anyByte
* @see #anyChar
* @see #anyDouble
* @see #anyFloat
* @see #anyLong
* @see #anyShort
* @see #anyString
* @see #any
* @see Tutorial
*/
protected final Integer anyInt = 0;
/**
* Matches any short or Short value received by a parameter of that type.
*
* This field can only be used as the argument value at the proper parameter position in a method/constructor
* invocation, when recording or verifying an expectation; it cannot be used anywhere else.
*
* 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.
* Any 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.
*
* @see #anyBoolean
* @see #anyByte
* @see #anyChar
* @see #anyDouble
* @see #anyFloat
* @see #anyInt
* @see #anyLong
* @see #anyString
* @see #any
* @see Tutorial
*/
protected final Short anyShort = 0;
/**
* Matches any byte or Byte value received by a parameter of that type.
*
* This field can only be used as the argument value at the proper parameter position in a method/constructor
* invocation, when recording or verifying an expectation; it cannot be used anywhere else.
*
* 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.
* Any 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.
*
* @see #anyBoolean
* @see #anyChar
* @see #anyDouble
* @see #anyFloat
* @see #anyInt
* @see #anyLong
* @see #anyShort
* @see #anyString
* @see #any
* @see Tutorial
*/
protected final Byte anyByte = 0;
/**
* Matches any boolean or Boolean value received by a parameter of that type.
*
* This field can only be used as the argument value at the proper parameter position in a method/constructor
* invocation, when recording or verifying an expectation; it cannot be used anywhere else.
*
* 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.
* Any 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.
*
* @see #anyByte
* @see #anyChar
* @see #anyDouble
* @see #anyFloat
* @see #anyInt
* @see #anyLong
* @see #anyShort
* @see #anyString
* @see #any
* @see Tutorial
*/
protected final Boolean anyBoolean = false;
/**
* Matches any char or Character value received by a parameter of that type.
*
* This field can only be used as the argument value at the proper parameter position in a method/constructor
* invocation, when recording or verifying an expectation; it cannot be used anywhere else.
*
* 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.
* Any 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.
*
* @see #anyBoolean
* @see #anyByte
* @see #anyDouble
* @see #anyFloat
* @see #anyInt
* @see #anyLong
* @see #anyShort
* @see #anyString
* @see #any
* @see Tutorial
*/
protected final Character anyChar = '\0';
/**
* Matches any double or Double value received by a parameter of that type.
*
* This field can only be used as the argument value at the proper parameter position in a method/constructor
* invocation, when recording or verifying an expectation; it cannot be used anywhere else.
*
* 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.
* Any 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.
*
* @see #anyBoolean
* @see #anyByte
* @see #anyChar
* @see #anyFloat
* @see #anyInt
* @see #anyLong
* @see #anyShort
* @see #anyString
* @see #any
* @see Tutorial
*/
protected final Double anyDouble = 0.0;
/**
* Matches any float or Float value received by a parameter of that type.
*
* This field can only be used as the argument value at the proper parameter position in a method/constructor
* invocation, when recording or verifying an expectation; it cannot be used anywhere else.
*
* 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.
* Any 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.
*
* @see #anyBoolean
* @see #anyByte
* @see #anyChar
* @see #anyDouble
* @see #anyInt
* @see #anyLong
* @see #anyString
* @see #anyShort
* @see #any
* @see Tutorial
*/
protected final Float anyFloat = 0.0F;
/**
* A non-negative value assigned to this field will be taken as the exact number of times that invocations matching
* the current expectation should occur during replay.
*
* @see #minTimes
* @see #maxTimes
* @see Tutorial
*/
protected int times;
/**
* A positive value assigned to this field will be taken as the minimum number of times that invocations matching
* the current expectation should occur during replay.
* Zero or a negative value means there is no lower limit, but only when applied to an expectation
* recorded in a test setup method, to a strict expectation, or to a full verification.
*
* If not specified, the default value of 1 (one) is used.
*
* The maximum number of times is automatically adjusted to allow any number of invocations.
* Both minTimes and maxTimes can be specified for the same expectation, as long as
* minTimes is assigned first.
*
* @see #times
* @see #maxTimes
* @see Tutorial
*/
protected int minTimes;
/**
* A non-negative value assigned to this field will be taken as the maximum number of times that invocations matching
* the current expectation should occur during replay.
* A negative value implies there is no upper limit.
*
* If not specified, there is no upper limit by default, except in the case of a strict expectation, where the
* default is 1 (one).
*
* Both minTimes and maxTimes can be specified for the same expectation, as long as
* minTimes is assigned first.
*
* @see #times
* @see #minTimes
* @see Tutorial
*/
protected int maxTimes;
@Nullable abstract TestOnlyPhase getCurrentPhase();
// Methods for argument matching ///////////////////////////////////////////////////////////////////////////////////
/**
* Applies a Hamcrest argument matcher for a parameter in the current expectation.
*
* 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.
* Any 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 argumentMatcher any org.hamcrest.Matcher object
*
* @return the value recorded inside the given Hamcrest matcher, or null if there is no such value to be
* found
*
* @see #with(Delegate)
*/
protected final T withArgThat(Matcher super T> argumentMatcher) {
HamcrestAdapter matcher = new HamcrestAdapter(argumentMatcher);
addMatcher(matcher);
@SuppressWarnings("unchecked") T argValue = (T) matcher.getInnerValue();
return argValue;
}
/**
* Applies a custom argument matcher for a parameter in the current expectation.
*
* The class of the given delegate object should define a single non-private
delegate method
* (plus any number of helper private methods).
* The name of the delegate method doesn't matter, but it must have a single parameter capable of receiving the
* relevant argument values.
*
* The return type of the delegate method should be boolean or void.
* In the first case, a return value of true will indicate a successful match for the actual invocation
* argument at replay time, while a return of false will fail to match the invocation.
* In the case of a void return type, the actual invocation argument should be validated through a suitable
* JUnit/TestNG assertion.
*
* 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.
* Any 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 objectWithDelegateMethod an instance of a class defining a single non-private
delegate method
*
* @return the default primitive value corresponding to T if it's a primitive wrapper type, or null
* otherwise
*
* @see #withArgThat(org.hamcrest.Matcher)
* @see Tutorial
*/
protected final T with(Delegate super T> objectWithDelegateMethod) {
Class> delegateClass = objectWithDelegateMethod.getClass();
Type[] genericInterfaces = delegateClass.getGenericInterfaces();
while (genericInterfaces.length == 0) {
delegateClass = delegateClass.getSuperclass();
genericInterfaces = delegateClass.getGenericInterfaces();
}
if (!(genericInterfaces[0] instanceof ParameterizedType)) {
throw new IllegalArgumentException("Delegate class lacks the parameter type");
}
ParameterizedType type = (ParameterizedType) genericInterfaces[0];
Type parameterType = type.getActualTypeArguments()[0];
addMatcher(new ReflectiveMatcher(objectWithDelegateMethod));
return DefaultValues.computeForWrapperType(parameterType);
}
private void addMatcher(@Nonnull ArgumentMatcher> matcher) {
TestOnlyPhase currentPhase = getCurrentPhase();
if (currentPhase != null) {
currentPhase.addArgMatcher(matcher);
}
}
/**
* Same as {@link #withEqual(Object)}, but matching any argument value of the appropriate type (null
* included).
*
* Consider using instead the "anyXyz" field appropriate to the parameter type:
* {@link #anyBoolean}, {@link #anyByte}, {@link #anyChar}, {@link #anyDouble}, {@link #anyFloat}, {@link #anyInt},
* {@link #anyLong}, {@link #anyShort}, {@link #anyString}, or {@link #any} for other reference types.
*
* 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.
* Any 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 arg an arbitrary value which will match any argument value in the replay phase
*
* @return the input argument
*
* @see Tutorial
*/
protected final T withAny(T arg) {
ArgumentMatcher> matcher;
if (arg instanceof String) matcher = AlwaysTrueMatcher.ANY_STRING;
else if (arg instanceof Integer) matcher = AlwaysTrueMatcher.ANY_INT;
else if (arg instanceof Boolean) matcher = AlwaysTrueMatcher.ANY_BOOLEAN;
else if (arg instanceof Character) matcher = AlwaysTrueMatcher.ANY_CHAR;
else if (arg instanceof Double) matcher = AlwaysTrueMatcher.ANY_DOUBLE;
else if (arg instanceof Float) matcher = AlwaysTrueMatcher.ANY_FLOAT;
else if (arg instanceof Long) matcher = AlwaysTrueMatcher.ANY_LONG;
else if (arg instanceof Byte) matcher = AlwaysTrueMatcher.ANY_BYTE;
else if (arg instanceof Short) matcher = AlwaysTrueMatcher.ANY_SHORT;
else matcher = AlwaysTrueMatcher.ANY_VALUE;
addMatcher(matcher);
return arg;
}
/**
* Captures the argument value passed into the associated expectation parameter, for each invocation that matches the
* expectation when the tested code is exercised.
* As each such value is captured, it gets added to the given list so that it can be inspected later.
* 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.
* Any 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 valueHolderForMultipleInvocations list into which the arguments received by matching invocations will be
* added
*
* @return the default value for type T
*
* @see Verifications#withCapture()
* @see Verifications#withCapture(Object)
* @see Tutorial
*/
protected final T withCapture(List valueHolderForMultipleInvocations) {
addMatcher(new CaptureMatcher(valueHolderForMultipleInvocations));
return null;
}
/**
* When passed as argument for an expectation, creates a new matcher that will check if the given value is
* {@link Object#equals(Object) equal} to the corresponding argument received by a matching invocation.
*
* The matcher is added to the end of the list of argument matchers for the invocation being recorded/verified.
* It cannot be reused for a different parameter.
*
* 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.
* Any arguments given as literals, local variables, or fields, will be implicitly matched as if
* withEqual(value) 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.
*
* Usually, this particular method should not be used.
* Instead, simply pass the desired argument value directly, without any matcher.
* Only when specifying values for a varargs method it's useful, and even then only when some other argument
* matcher is also used.
*
* @param arg the expected argument value
*
* @return the given argument
*
* @see Tutorial
*/
protected final T withEqual(T arg) {
TestOnlyPhase currentPhase = getCurrentPhase();
if (currentPhase != null) {
Map