View Javadoc
1   /*
2    * MIT License
3    * Copyright (c) 2006-2025 JMockit developers
4    * See LICENSE file for full license text.
5    */
6   package mockit.internal.faking;
7   
8   import static mockit.internal.util.Utilities.NO_ARGS;
9   
10  import edu.umd.cs.findbugs.annotations.NonNull;
11  import edu.umd.cs.findbugs.annotations.Nullable;
12  
13  import java.lang.reflect.Constructor;
14  import java.lang.reflect.Member;
15  
16  import mockit.internal.BaseInvocation;
17  import mockit.internal.state.TestRun;
18  
19  import org.checkerframework.checker.index.qual.NonNegative;
20  
21  /**
22   * An invocation to a {@linkplain mockit.Mock fake} method.
23   */
24  public final class FakeInvocation extends BaseInvocation {
25      @NonNull
26      private final FakeState fakeState;
27      @NonNull
28      private final String fakedClassDesc;
29      @NonNull
30      private final String fakedMethodName;
31      @NonNull
32      private final String fakedMethodDesc;
33      boolean proceeding;
34  
35      @NonNull // called by generated bytecode
36      public static FakeInvocation create(@Nullable Object invokedInstance, @Nullable Object[] invokedArguments,
37              @NonNull String fakeClassDesc, @NonNegative int fakeStateIndex, @NonNull String fakedClassDesc,
38              @NonNull String fakedMethodName, @NonNull String fakedMethodDesc) {
39          Object fake = TestRun.getFake(fakeClassDesc, invokedInstance);
40          assert fake != null;
41          FakeState fakeState = TestRun.getFakeStates().getFakeState(fake, fakeStateIndex);
42          Object[] args = invokedArguments == null ? NO_ARGS : invokedArguments;
43          return new FakeInvocation(invokedInstance, args, fakeState, fakedClassDesc, fakedMethodName, fakedMethodDesc);
44      }
45  
46      FakeInvocation(@Nullable Object invokedInstance, @NonNull Object[] invokedArguments, @NonNull FakeState fakeState,
47              @NonNull String fakedClassDesc, @NonNull String fakedMethodName, @NonNull String fakedMethodDesc) {
48          super(invokedInstance, invokedArguments, fakeState.getTimesInvoked());
49          this.fakeState = fakeState;
50          this.fakedClassDesc = fakedClassDesc;
51          this.fakedMethodName = fakedMethodName;
52          this.fakedMethodDesc = fakedMethodDesc;
53      }
54  
55      @NonNull
56      @Override
57      protected Member findRealMember() {
58          Object invokedInstance = getInvokedInstance();
59  
60          if (invokedInstance != null) {
61              Class<?> mockedClass = invokedInstance.getClass();
62              return fakeState.getRealMethodOrConstructor(mockedClass, fakedMethodName, fakedMethodDesc);
63          }
64  
65          return fakeState.getRealMethodOrConstructor(fakedClassDesc, fakedMethodName, fakedMethodDesc);
66      }
67  
68      @SuppressWarnings("WeakerAccess") // called from generated bytecode
69      public boolean shouldProceedIntoConstructor() {
70          if (proceeding && getInvokedMember() instanceof Constructor) {
71              fakeState.clearProceedIndicator();
72              return true;
73          }
74  
75          return false;
76      }
77  
78      @Override
79      public void prepareToProceed() {
80          fakeState.prepareToProceed(this);
81          proceeding = true;
82      }
83  
84      public void prepareToProceedFromNonRecursiveMock() {
85          fakeState.prepareToProceedFromNonRecursiveFake(this);
86          proceeding = true;
87      }
88  
89      @Override
90      public void cleanUpAfterProceed() {
91          fakeState.clearProceedIndicator();
92      }
93  }