1
2
3
4
5
6 package mockit.internal.state;
7
8 import edu.umd.cs.findbugs.annotations.NonNull;
9 import edu.umd.cs.findbugs.annotations.Nullable;
10
11 import mockit.internal.expectations.RecordAndReplayExecution;
12 import mockit.internal.expectations.mocking.FieldTypeRedefinitions;
13 import mockit.internal.expectations.state.ExecutingTest;
14 import mockit.internal.faking.FakeClasses;
15 import mockit.internal.faking.FakeStates;
16 import mockit.internal.injection.TestedClassInstantiations;
17 import mockit.internal.util.StackTrace;
18
19
20
21
22
23 public final class TestRun {
24 private static final TestRun INSTANCE = new TestRun();
25
26 private TestRun() {
27 }
28
29
30
31
32 private static final ThreadLocal<Integer> noMockingCount = new ThreadLocal<>() {
33 @Override
34 protected Integer initialValue() {
35 return 0;
36 }
37
38 @Override
39 public void set(Integer valueToAdd) {
40 super.set(get() + valueToAdd);
41 }
42 };
43
44
45 private int testId;
46
47 @Nullable
48 private Class<?> currentTestClass;
49 @Nullable
50 private Object currentTestInstance;
51 @Nullable
52 private FieldTypeRedefinitions fieldTypeRedefinitions;
53 @Nullable
54 private TestedClassInstantiations testedClassInstantiations;
55
56 @NonNull
57 private final MockFixture mockFixture = new MockFixture();
58
59 @NonNull
60 private final ExecutingTest executingTest = new ExecutingTest();
61 @NonNull
62 private final FakeClasses fakeClasses = new FakeClasses();
63
64
65
66
67 public static boolean isInsideNoMockingZone() {
68 return noMockingCount.get() > 0;
69 }
70
71 @Nullable
72 public static Class<?> getCurrentTestClass() {
73 return INSTANCE.currentTestClass;
74 }
75
76 @Nullable
77 public static Object getCurrentTestInstance() {
78 return INSTANCE.currentTestInstance;
79 }
80
81 public static int getTestId() {
82 return INSTANCE.testId;
83 }
84
85 @Nullable
86 public static FieldTypeRedefinitions getFieldTypeRedefinitions() {
87 return INSTANCE.fieldTypeRedefinitions;
88 }
89
90 @Nullable
91 public static TestedClassInstantiations getTestedClassInstantiations() {
92 return INSTANCE.testedClassInstantiations;
93 }
94
95 @NonNull
96 public static MockFixture mockFixture() {
97 return INSTANCE.mockFixture;
98 }
99
100 @NonNull
101 public static ExecutingTest getExecutingTest() {
102 return INSTANCE.executingTest;
103 }
104
105 @Nullable
106 public static RecordAndReplayExecution getRecordAndReplayForRunningTest() {
107 return INSTANCE.executingTest.getCurrentRecordAndReplay();
108 }
109
110 @NonNull
111 public static RecordAndReplayExecution getOrCreateRecordAndReplayForRunningTest() {
112 return INSTANCE.executingTest.getOrCreateRecordAndReplay();
113 }
114
115 @NonNull
116 public static RecordAndReplayExecution getRecordAndReplayForVerifications() {
117 return INSTANCE.executingTest.getRecordAndReplayForVerifications();
118 }
119
120 @NonNull
121 public static FakeClasses getFakeClasses() {
122 return INSTANCE.fakeClasses;
123 }
124
125 @NonNull
126 public static FakeStates getFakeStates() {
127 return INSTANCE.fakeClasses.fakeStates;
128 }
129
130
131
132
133 public static void setCurrentTestClass(@Nullable Class<?> testClass) {
134 INSTANCE.currentTestClass = testClass;
135 }
136
137 public static void prepareForNextTest() {
138 INSTANCE.testId++;
139 INSTANCE.executingTest.setRecordAndReplay(null);
140 }
141
142 public static void enterNoMockingZone() {
143 noMockingCount.set(1);
144 }
145
146 public static void exitNoMockingZone() {
147 noMockingCount.set(-1);
148 }
149
150 public static void clearNoMockingZone() {
151 noMockingCount.remove();
152 }
153
154 public static void clearCurrentTestInstance() {
155 INSTANCE.currentTestInstance = null;
156 }
157
158 public static void setRunningIndividualTest(@NonNull Object testInstance) {
159 INSTANCE.currentTestInstance = testInstance;
160 }
161
162 public static void setFieldTypeRedefinitions(@Nullable FieldTypeRedefinitions redefinitions) {
163 INSTANCE.fieldTypeRedefinitions = redefinitions;
164 }
165
166 public static void setTestedClassInstantiations(@Nullable TestedClassInstantiations testedClassInstantiations) {
167 INSTANCE.testedClassInstantiations = testedClassInstantiations;
168 }
169
170 public static void finishCurrentTestExecution() {
171 INSTANCE.executingTest.finishExecution();
172 }
173
174
175
176
177 @SuppressWarnings({ "StaticMethodOnlyUsedInOneClass", "SimplifiableIfStatement" })
178 public static boolean updateFakeState(@NonNull String fakeClassDesc, @Nullable Object mockedInstance,
179 int fakeStateIndex) {
180 Object fake = getFake(fakeClassDesc, mockedInstance);
181
182 if (fake == null) {
183 return false;
184 }
185
186 if (fakeStateIndex < 0) {
187 return true;
188 }
189
190 return getFakeStates().updateFakeState(fake, fakeStateIndex);
191 }
192
193 @Nullable
194 public static Object getFake(@NonNull String fakeClassDesc, @Nullable Object mockedInstance) {
195 return INSTANCE.fakeClasses.getFake(fakeClassDesc, mockedInstance);
196 }
197
198
199
200 public static void ensureThatClassIsInitialized(@NonNull Class<?> aClass) {
201 boolean previousFlag = INSTANCE.executingTest.setShouldIgnoreMockingCallbacks(true);
202
203 try {
204 Class.forName(aClass.getName(), true, aClass.getClassLoader());
205 } catch (ClassNotFoundException ignore) {
206 } catch (LinkageError e) {
207 StackTrace.filterStackTrace(e);
208 e.printStackTrace();
209 } finally {
210 INSTANCE.executingTest.setShouldIgnoreMockingCallbacks(previousFlag);
211 }
212 }
213
214
215
216
217
218
219 public static boolean isInsideTestMethodOrAssertThrows() {
220
221
222 return StackWalker.getInstance()
223 .walk(stream -> stream.anyMatch(frame -> "org.junit.jupiter.api.Assertions".equals(frame.getClassName())
224 && "assertThrows".equals(frame.getMethodName())));
225 }
226
227 }