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