All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mockit.internal.expectations.Expectation Maven / Gradle / Ivy

Go to download

JMockit is a Java toolkit for automated developer testing. It contains APIs for the creation of the objects to be tested, for mocking dependencies, and for faking external APIs; JUnit (4 & 5) and TestNG test runners are supported. It also contains an advanced code coverage tool.

There is a newer version: 1.49
Show newest version
/*
 * 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.*;

final class Expectation
{
   @Nullable final RecordPhase recordPhase;
   @Nonnull final ExpectedInvocation invocation;
   @Nonnull final InvocationConstraints constraints;
   @Nullable private InvocationResults results;
   boolean executedRealImplementation;

   Expectation(@Nonnull ExpectedInvocation invocation)
   {
      recordPhase = null;
      this.invocation = invocation;
      constraints = new InvocationConstraints(false, true);
   }

   Expectation(
      @Nullable RecordPhase recordPhase, @Nonnull ExpectedInvocation invocation, boolean strict, boolean nonStrict)
   {
      this.recordPhase = recordPhase;
      this.invocation = invocation;
      constraints = new InvocationConstraints(strict, nonStrict);
   }

   @Nonnull
   InvocationResults getResults()
   {
      if (results == null) {
         results = new InvocationResults(invocation, constraints);
      }

      return results;
   }

   @Nullable
   Object produceResult(@Nullable Object invokedObject, @Nonnull Object[] invocationArgs) throws Throwable
   {
      if (results == null) {
         return invocation.getDefaultValueForReturnType(null);
      }

      return results.produceResult(invokedObject, invocationArgs);
   }

   @Nonnull
   Class getReturnType()
   {
      return TypeDescriptor.getReturnType(invocation.getSignatureWithResolvedReturnType());
   }

   void clearNextInstanceToMatchIfRecording()
   {
      if (recordPhase != null) {
         recordPhase.setNextInstanceToMatch(null);
      }
   }

   void addSequenceOfReturnValues(@Nullable Object firstValue, @Nullable Object[] remainingValues)
   {
      InvocationResults sequence = getResults();

      if (remainingValues == null) {
         addFirstReturnValue(firstValue);
         sequence.addReturnValue(null);
      }
      else if (remainingValues.length == 0) {
         addFirstReturnValue(firstValue);
      }
      else if (!new SequenceOfReturnValues(this, firstValue, remainingValues).addResultWithSequenceOfValues()) {
         sequence.addReturnValue(firstValue);
         sequence.addReturnValues(remainingValues);
      }
   }

   private void addFirstReturnValue(@Nullable Object firstValue)
   {
      if (firstValue == null) {
         getResults().addReturnValueResult(null);
      }
      else {
         Class returnType = getReturnType();
         new ReturnTypeConversion(this, returnType, firstValue).addConvertedValueOrValues();
      }
   }

   @SuppressWarnings("UnnecessaryFullyQualifiedName")
   void addResult(@Nullable Object value)
   {
      if (value == null) {
         getResults().addReturnValueResult(null);
      }
      else if (isReplacementInstance(value)) {
         invocation.replacementInstance = value;
      }
      else if (value instanceof Throwable) {
         getResults().addThrowable((Throwable) value);
      }
      else if (value instanceof mockit.Delegate) {
         getResults().addDelegatedResult((mockit.Delegate) value);
      }
      else {
         Class rt = getReturnType();

         if (rt.isInstance(value)) {
            clearNextInstanceToMatchIfRecording();
            getResults().addReturnValueResult(value);
         }
         else {
            new ReturnTypeConversion(this, rt, value).addConvertedValue();
         }
      }
   }

   private boolean isReplacementInstance(@Nonnull Object value)
   {
      return invocation.isConstructor() && value.getClass().isInstance(invocation.instance);
   }

   void setCustomErrorMessage(@Nullable CharSequence message) { invocation.customErrorMessage = message; }

   @Nullable
   Error verifyConstraints(
      @Nonnull ExpectedInvocation replayInvocation, @Nonnull Object[] replayArgs,
      int minInvocations, int maxInvocations)
   {
      Error error = verifyConstraints(minInvocations);

      if (error != null) {
         return error;
      }

      return constraints.verifyUpperLimit(replayInvocation, replayArgs, maxInvocations, invocation.customErrorMessage);
   }

   @Nullable
   Error verifyConstraints(int minInvocations)
   {
      return constraints.verifyLowerLimit(invocation, minInvocations);
   }

   @Nullable
   Object executeRealImplementation(@Nonnull Object replacementInstance, @Nonnull Object[] args) throws Throwable
   {
      return getResults().executeRealImplementation(replacementInstance, args);
   }

   boolean isRedundantRecordedExpectation(@Nonnull Expectation verification)
   {
      if (recordPhase == null || constraints.minInvocations <= 0) {
         return false;
      }

      List> recordingMatchers = invocation.arguments.getMatchers();
      List> verificationMatchers = verification.invocation.arguments.getMatchers();

      if (recordingMatchers == verificationMatchers) {
         return true;
      }

      if (recordingMatchers == null || verificationMatchers == null) {
         return false;
      }

      int n = recordingMatchers.size();

      if (verificationMatchers.size() != n) {
         return false;
      }

      for (int i = 0; i < n; i++) {
         ArgumentMatcher recordedMatcher = recordingMatchers.get(i);
         ArgumentMatcher verificationMatcher = verificationMatchers.get(i);

         if (recordedMatcher != verificationMatcher && !recordedMatcher.equals(verificationMatcher)) {
            return false;
         }
      }

      return true;
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy