All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
mockit.internal.expectations.BaseVerificationPhase Maven / Gradle / Ivy
Go to download
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 Rogério Liesenfeld
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit.internal.expectations;
import java.util.*;
import javax.annotation.*;
import mockit.internal.expectations.argumentMatching.*;
import mockit.internal.expectations.invocation.*;
import mockit.internal.util.*;
public abstract class BaseVerificationPhase extends TestOnlyPhase
{
@Nonnull final List expectationsInReplayOrder;
@Nonnull final List invocationInstancesInReplayOrder;
@Nonnull final List invocationArgumentsInReplayOrder;
private boolean allMockedInvocationsDuringReplayMustBeVerified;
@Nullable private Object[] mockedTypesAndInstancesToFullyVerify;
@Nonnull private final List currentVerifiedExpectations;
@Nullable private Expectation currentVerification;
protected int replayIndex;
@Nullable protected Error pendingError;
protected BaseVerificationPhase(
@Nonnull RecordAndReplayExecution recordAndReplay,
@Nonnull List expectationsInReplayOrder,
@Nonnull List invocationInstancesInReplayOrder,
@Nonnull List invocationArgumentsInReplayOrder)
{
super(recordAndReplay);
this.expectationsInReplayOrder = expectationsInReplayOrder;
this.invocationInstancesInReplayOrder = invocationInstancesInReplayOrder;
this.invocationArgumentsInReplayOrder = invocationArgumentsInReplayOrder;
currentVerifiedExpectations = new ArrayList();
}
public final void setAllInvocationsMustBeVerified() { allMockedInvocationsDuringReplayMustBeVerified = true; }
public final boolean isFullyVerified() { return allMockedInvocationsDuringReplayMustBeVerified; }
public final void setMockedTypesToFullyVerify(@Nonnull Object[] mockedTypesAndInstancesToFullyVerify)
{
this.mockedTypesAndInstancesToFullyVerify = mockedTypesAndInstancesToFullyVerify;
}
@Nonnull
protected final Expectation expectationBeingVerified()
{
if (currentVerification == null) {
throw new IllegalStateException(
"Missing invocation to mocked type at this point; please make sure there is an associated " +
"mock field or mock parameter in scope");
}
return currentVerification;
}
@Nullable @Override
final Object handleInvocation(
@Nullable Object mock, int mockAccess, @Nonnull String mockClassDesc, @Nonnull String mockNameAndDesc,
@Nullable String genericSignature, boolean withRealImpl, @Nonnull Object[] args)
{
if (pendingError != null) {
recordAndReplay.setErrorThrown(pendingError);
pendingError = null;
return null;
}
matchInstance =
mock != null && (
nextInstanceToMatch != null && mock == nextInstanceToMatch ||
recordAndReplay.executionState.getReplacementInstanceForMethodInvocation(mock, mockNameAndDesc) != null ||
isEnumElement(mock)
);
ExpectedInvocation currentInvocation = new ExpectedInvocation(
mock, mockAccess, mockClassDesc, mockNameAndDesc, matchInstance, genericSignature, args);
currentInvocation.arguments.setMatchers(argMatchers);
currentVerification = new Expectation(currentInvocation);
currentExpectation = null;
currentVerifiedExpectations.clear();
findNonStrictExpectation(mock, mockClassDesc, mockNameAndDesc, args);
argMatchers = null;
if (matchInstance) {
nextInstanceToMatch = null;
}
if (recordAndReplay.getErrorThrown() != null) {
return null;
}
if (currentExpectation == null) {
pendingError = currentVerification.invocation.errorForMissingInvocation();
currentExpectation = currentVerification;
}
return currentExpectation.invocation.getDefaultValueForReturnType(this);
}
abstract void findNonStrictExpectation(
@Nullable Object mock, @Nonnull String mockClassDesc, @Nonnull String mockNameAndDesc, @Nonnull Object[] args);
final boolean matches(
@Nullable Object mock, @Nonnull String mockClassDesc, @Nonnull String mockNameAndDesc, @Nonnull Object[] args,
@Nonnull Expectation replayExpectation, @Nullable Object replayInstance, @Nonnull Object[] replayArgs)
{
ExpectedInvocation invocation = replayExpectation.invocation;
boolean constructor = invocation.isConstructor();
Map replacementMap = getReplacementMap();
if (invocation.isMatch(mock, mockClassDesc, mockNameAndDesc, replacementMap)) {
boolean matching;
if (mock == null || invocation.instance == null) {
matching = true;
}
else if (matchInstance) {
matching = recordAndReplay.executionState.isEquivalentInstance(invocation.instance, mock);
}
else if (constructor) {
matching = true;
}
else {
matching = !recordAndReplay.executionState.areInDifferentEquivalenceSets(invocation.instance, mock);
}
if (matching) {
InvocationArguments invocationArguments = invocation.arguments;
List> originalMatchers = invocationArguments.getMatchers();
Object[] originalArgs = invocationArguments.prepareForVerification(args, argMatchers);
Map instanceMap = getInstanceMap();
boolean argumentsMatch = invocationArguments.isMatch(replayArgs, instanceMap);
invocationArguments.setValuesAndMatchers(originalArgs, originalMatchers);
if (argumentsMatch) {
if (constructor) {
instanceMap.put(replayInstance, mock);
}
addVerifiedExpectation(replayExpectation, replayArgs, argMatchers);
return true;
}
}
}
return false;
}
private void addVerifiedExpectation(
@Nonnull Expectation expectation, @Nonnull Object[] args, @Nullable List> matchers)
{
int i = expectationsInReplayOrder.indexOf(expectation);
addVerifiedExpectation(new VerifiedExpectation(expectation, args, matchers, i));
}
void addVerifiedExpectation(@Nonnull VerifiedExpectation verifiedExpectation)
{
recordAndReplay.executionState.verifiedExpectations.add(verifiedExpectation);
currentVerifiedExpectations.add(verifiedExpectation);
}
final void mapNewInstanceToReplacementIfApplicable(@Nullable Object mock)
{
if (mock != null && !matchInstance) {
assert currentExpectation != null;
ExpectedInvocation invocation = currentExpectation.invocation;
if (invocation.isConstructor()) {
Object replacementInstance = invocation.replacementInstance;
if (replacementInstance != null) {
getReplacementMap().put(mock, replacementInstance);
}
}
}
}
@Override
public final void setMaxInvocationCount(int maxInvocations)
{
if (maxInvocations == 0 || pendingError == null) {
super.setMaxInvocationCount(maxInvocations);
}
}
@Nullable
protected Error endVerification()
{
if (pendingError != null) {
return pendingError;
}
if (allMockedInvocationsDuringReplayMustBeVerified) {
return validateThatAllInvocationsWereVerified();
}
return null;
}
@Nullable
private Error validateThatAllInvocationsWereVerified()
{
List notVerified = new ArrayList();
for (int i = 0; i < expectationsInReplayOrder.size(); i++) {
Expectation replayExpectation = expectationsInReplayOrder.get(i);
if (replayExpectation != null && isEligibleForFullVerification(replayExpectation)) {
Object[] replayArgs = invocationArgumentsInReplayOrder.get(i);
if (!wasVerified(replayExpectation, replayArgs)) {
notVerified.add(replayExpectation);
}
}
}
if (!notVerified.isEmpty()) {
if (mockedTypesAndInstancesToFullyVerify == null) {
Expectation firstUnexpected = notVerified.get(0);
return firstUnexpected.invocation.errorForUnexpectedInvocation();
}
return validateThatUnverifiedInvocationsAreAllowed(notVerified);
}
return null;
}
private static boolean isEligibleForFullVerification(@Nonnull Expectation replayExpectation)
{
return !replayExpectation.executedRealImplementation && replayExpectation.constraints.minInvocations <= 0;
}
private boolean wasVerified(@Nonnull Expectation replayExpectation, @Nonnull Object[] replayArgs)
{
InvocationArguments invokedArgs = replayExpectation.invocation.arguments;
List expectationsVerified = recordAndReplay.executionState.verifiedExpectations;
for (int j = 0; j < expectationsVerified.size(); j++) {
VerifiedExpectation verified = expectationsVerified.get(j);
if (verified.expectation == replayExpectation) {
Object[] storedArgs = invokedArgs.prepareForVerification(verified.arguments, verified.argMatchers);
boolean argumentsMatch = invokedArgs.isMatch(replayArgs, getInstanceMap());
invokedArgs.setValuesWithNoMatchers(storedArgs);
if (argumentsMatch) {
if (shouldDiscardInformationAboutVerifiedInvocationOnceUsed()) {
expectationsVerified.remove(j);
}
return true;
}
}
}
invokedArgs.setValuesWithNoMatchers(replayArgs);
return false;
}
boolean shouldDiscardInformationAboutVerifiedInvocationOnceUsed() { return false; }
@Nullable
private Error validateThatUnverifiedInvocationsAreAllowed(@Nonnull List unverified)
{
for (Expectation expectation : unverified) {
ExpectedInvocation invocation = expectation.invocation;
if (isInvocationToBeVerified(invocation)) {
return invocation.errorForUnexpectedInvocation();
}
}
return null;
}
private boolean isInvocationToBeVerified(@Nonnull ExpectedInvocation unverifiedInvocation)
{
String invokedClassName = unverifiedInvocation.getClassName();
Object invokedInstance = unverifiedInvocation.instance;
assert mockedTypesAndInstancesToFullyVerify != null;
for (Object mockedTypeOrInstance : mockedTypesAndInstancesToFullyVerify) {
if (mockedTypeOrInstance instanceof Class) {
Class> mockedType = (Class>) mockedTypeOrInstance;
if (invokedClassName.equals(mockedType.getName())) {
return true;
}
}
else if (invokedInstance == null) {
ClassLoader loader = mockedTypeOrInstance.getClass().getClassLoader();
Class> invokedClass = ClassLoad.loadFromLoader(loader, invokedClassName);
if (invokedClass.isInstance(mockedTypeOrInstance)) {
return true;
}
}
else if (unverifiedInvocation.matchInstance) {
if (mockedTypeOrInstance == invokedInstance) {
return true;
}
}
else if (invokedInstance.getClass().isInstance(mockedTypeOrInstance)) {
return true;
}
}
return false;
}
@Nullable
public final Object getArgumentValueForCurrentVerification(int parameterIndex)
{
List verifiedExpectations = recordAndReplay.executionState.verifiedExpectations;
if (verifiedExpectations.isEmpty()) {
return expectationBeingVerified().invocation.getArgumentValues()[parameterIndex];
}
VerifiedExpectation lastMatched = verifiedExpectations.get(verifiedExpectations.size() - 1);
return lastMatched.arguments[parameterIndex];
}
public final void discardReplayedInvocations()
{
if (mockedTypesAndInstancesToFullyVerify == null) {
expectationsInReplayOrder.clear();
invocationArgumentsInReplayOrder.clear();
}
else {
for (int i = expectationsInReplayOrder.size() - 1; i >= 0; i--) {
Expectation expectation = expectationsInReplayOrder.get(i);
if (isInvocationToBeVerified(expectation.invocation)) {
expectationsInReplayOrder.remove(i);
invocationArgumentsInReplayOrder.remove(i);
}
}
}
}
@Nonnull
public final List getNewInstancesMatchingVerifiedConstructorInvocation()
{
List newInstances = new ArrayList();
for (VerifiedExpectation verifiedExpectation : currentVerifiedExpectations) {
//noinspection unchecked
T newInstance = (T) verifiedExpectation.captureNewInstance();
newInstances.add(newInstance);
}
return newInstances;
}
}