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 JMockit developers
* 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;
int replayIndex;
@Nullable protected Error pendingError;
@Nullable protected ExpectedInvocation matchingInvocationWithDifferentArgs;
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 void setMockedTypesToFullyVerify(@Nonnull Object[] mockedTypesAndInstancesToFullyVerify) {
this.mockedTypesAndInstancesToFullyVerify = mockedTypesAndInstancesToFullyVerify;
}
@Nullable
protected final Expectation expectationBeingVerified() { 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 &&
(recordAndReplay.executionState.equivalentInstances.isReplacementInstance(mock, mockNameAndDesc) || 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();
List matchingInvocationsWithDifferentArgs = findExpectation(mock, mockClassDesc, mockNameAndDesc, args);
argMatchers = null;
if (recordAndReplay.getErrorThrown() != null) {
return null;
}
if (currentExpectation == null) {
pendingError = currentVerification.invocation.errorForMissingInvocation(matchingInvocationsWithDifferentArgs);
currentExpectation = currentVerification;
}
return currentExpectation.invocation.getDefaultValueForReturnType();
}
@Nonnull
abstract List findExpectation(
@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();
matchingInvocationWithDifferentArgs = null;
if (invocation.isMatch(mock, mockClassDesc, mockNameAndDesc, replacementMap)) {
boolean matching;
if (mock == null || invocation.instance == null || constructor && !matchInstance) {
matching = true;
}
else {
matching = recordAndReplay.executionState.equivalentInstances.areMatchingInstances(matchInstance, invocation.instance, mock);
}
if (matching) {
matchingInvocationWithDifferentArgs = invocation;
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);
return true;
}
}
}
return false;
}
abstract void addVerifiedExpectation(@Nonnull Expectation expectation, @Nonnull Object[] args);
final void addVerifiedExpectation(@Nonnull VerifiedExpectation verifiedExpectation) {
recordAndReplay.executionState.verifiedExpectations.add(verifiedExpectation);
currentVerifiedExpectations.add(verifiedExpectation);
}
@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, n = expectationsInReplayOrder.size(); i < n; i++) {
Expectation replayExpectation = expectationsInReplayOrder.get(i);
if (replayExpectation != null && isEligibleForFullVerification(replayExpectation)) {
Object[] replayArgs = invocationArgumentsInReplayOrder.get(i);
if (!wasVerified(replayExpectation, replayArgs, i)) {
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, @Nonnegative int expectationIndex) {
InvocationArguments invokedArgs = replayExpectation.invocation.arguments;
List verifiedExpectations = recordAndReplay.executionState.verifiedExpectations;
for (int j = 0, n = verifiedExpectations.size(); j < n; j++) {
VerifiedExpectation verified = verifiedExpectations.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 && verified.matchesReplayIndex(expectationIndex)) {
if (shouldDiscardInformationAboutVerifiedInvocationOnceUsed()) {
verifiedExpectations.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(@Nonnegative int parameterIndex) {
List verifiedExpectations = recordAndReplay.executionState.verifiedExpectations;
if (verifiedExpectations.isEmpty()) {
Expectation expectation = expectationBeingVerified();
return expectation == null ? null : expectation.invocation.getArgumentValues()[parameterIndex];
}
VerifiedExpectation lastMatched = verifiedExpectations.get(verifiedExpectations.size() - 1);
return lastMatched.arguments[parameterIndex];
}
@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;
}
}