• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / jmockit1 / 496

15 Nov 2025 05:33PM UTC coverage: 72.192% (-0.008%) from 72.2%
496

push

github

web-flow
Merge pull request #412 from hazendaz/renovate/major-spring-core

Update spring core to v7 (major)

5677 of 8360 branches covered (67.91%)

Branch coverage included in aggregate %.

11922 of 16018 relevant lines covered (74.43%)

0.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.69
/main/src/main/java/mockit/integration/junit5/JMockitExtension.java
1
/*
2
 * MIT License
3
 * Copyright (c) 2006-2025 JMockit developers
4
 * See LICENSE file for full license text.
5
 */
6
package mockit.integration.junit5;
7

8
import static mockit.internal.util.StackTrace.filterStackTrace;
9

10
import edu.umd.cs.findbugs.annotations.NonNull;
11
import edu.umd.cs.findbugs.annotations.Nullable;
12

13
import java.lang.reflect.Method;
14
import java.util.Arrays;
15
import java.util.stream.Collectors;
16

17
import mockit.Capturing;
18
import mockit.Injectable;
19
import mockit.Mocked;
20
import mockit.Tested;
21
import mockit.integration.TestRunnerDecorator;
22
import mockit.internal.expectations.RecordAndReplayExecution;
23
import mockit.internal.state.SavePoint;
24
import mockit.internal.state.TestRun;
25
import mockit.internal.util.Utilities;
26

27
import org.junit.jupiter.api.BeforeAll;
28
import org.junit.jupiter.api.BeforeEach;
29
import org.junit.jupiter.api.Nested;
30
import org.junit.jupiter.api.extension.AfterAllCallback;
31
import org.junit.jupiter.api.extension.AfterEachCallback;
32
import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
33
import org.junit.jupiter.api.extension.BeforeAllCallback;
34
import org.junit.jupiter.api.extension.BeforeEachCallback;
35
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
36
import org.junit.jupiter.api.extension.ExtensionContext;
37
import org.junit.jupiter.api.extension.ParameterContext;
38
import org.junit.jupiter.api.extension.ParameterResolver;
39
import org.junit.jupiter.api.extension.TestExecutionExceptionHandler;
40
import org.junit.jupiter.api.extension.TestInstancePostProcessor;
41

42
public final class JMockitExtension extends TestRunnerDecorator implements BeforeAllCallback, AfterAllCallback,
1✔
43
        TestInstancePostProcessor, BeforeEachCallback, AfterEachCallback, BeforeTestExecutionCallback,
44
        AfterTestExecutionCallback, ParameterResolver, TestExecutionExceptionHandler {
45
    @Nullable
46
    private SavePoint savePointForTestClass;
47
    @Nullable
48
    private SavePoint savePointForTest;
49
    @Nullable
50
    private SavePoint savePointForTestMethod;
51
    @Nullable
52
    private Throwable thrownByTest;
53
    private Object[] parameterValues;
54
    private ParamValueInitContext initContext = new ParamValueInitContext(null, null, null,
1✔
55
            "No callbacks have been processed, preventing parameter population");
56

57
    @Override
58
    public void beforeAll(@NonNull ExtensionContext context) {
59
        if (!isRegularTestClass(context)) {
1!
60
            return;
×
61
        }
62

63
        @Nullable
64
        Class<?> testClass = context.getTestClass().orElse(null);
1✔
65
        savePointForTestClass = new SavePoint();
1✔
66
        // Ensure JMockit state and test class logic is handled before any test instance is created
67
        updateTestClassState(null, testClass);
1✔
68

69
        if (testClass == null) {
1!
70
            initContext = new ParamValueInitContext(null, null, null,
×
71
                    "@BeforeAll setup failed to acquire 'Class' of test");
72
            return;
×
73
        }
74

75
        // @BeforeAll can be used on instance methods depending on @TestInstance(PER_CLASS) usage
76
        Object testInstance = context.getTestInstance().orElse(null);
1✔
77
        Method beforeAllMethod = Utilities.getAnnotatedDeclaredMethod(testClass, BeforeAll.class);
1✔
78
        if (testInstance == null) {
1!
79
            initContext = new ParamValueInitContext(null, testClass, beforeAllMethod,
1✔
80
                    "@BeforeAll setup failed to acquire instance of test class");
81
            return;
1✔
82
        }
83

84
        if (beforeAllMethod != null) {
×
85
            initContext = new ParamValueInitContext(testInstance, testClass, beforeAllMethod, null);
×
86
            parameterValues = createInstancesForAnnotatedParameters(testInstance, beforeAllMethod, null);
×
87
        }
88
    }
×
89

90
    private static boolean isRegularTestClass(@NonNull ExtensionContext context) {
91
        Class<?> testClass = context.getTestClass().orElse(null);
1✔
92
        return testClass != null && !testClass.isAnnotationPresent(Nested.class);
1!
93
    }
94

95
    @Override
96
    public void postProcessTestInstance(@NonNull Object testInstance, @NonNull ExtensionContext context) {
97
        if (!isRegularTestClass(context)) {
1!
98
            return;
×
99
        }
100

101
        TestRun.enterNoMockingZone();
1✔
102

103
        try {
104
            handleMockFieldsForWholeTestClass(testInstance);
1✔
105
        } finally {
106
            TestRun.exitNoMockingZone();
1✔
107
        }
108

109
        TestRun.setRunningIndividualTest(testInstance);
1✔
110
    }
1✔
111

112
    @Override
113
    public void beforeEach(@NonNull ExtensionContext context) {
114
        Object testInstance = context.getTestInstance().orElse(null);
1✔
115
        Class<?> testClass = context.getTestClass().orElse(null);
1✔
116
        if (testInstance == null) {
1!
117
            initContext = new ParamValueInitContext(null, null, null,
×
118
                    "@BeforeEach setup failed to acquire instance of test class");
119
            return;
×
120
        }
121

122
        TestRun.prepareForNextTest();
1✔
123
        TestRun.enterNoMockingZone();
1✔
124

125
        try {
126
            savePointForTest = new SavePoint();
1✔
127
            createInstancesForTestedFieldsBeforeSetup(testInstance);
1✔
128

129
            if (testClass == null) {
1!
130
                initContext = new ParamValueInitContext(null, null, null,
×
131
                        "@BeforeEach setup failed to acquire Class<?> of test");
132
                return;
×
133
            }
134

135
            Method beforeEachMethod = Utilities.getAnnotatedDeclaredMethod(testClass, BeforeEach.class);
1✔
136
            if (beforeEachMethod != null) {
1✔
137
                initContext = new ParamValueInitContext(testInstance, testClass, beforeEachMethod, null);
1✔
138
                parameterValues = createInstancesForAnnotatedParameters(testInstance, beforeEachMethod, null);
1✔
139
            }
140
        } finally {
141
            TestRun.exitNoMockingZone();
1✔
142
        }
143
    }
1✔
144

145
    @Override
146
    public void beforeTestExecution(@NonNull ExtensionContext context) {
147
        Class<?> testClass = context.getTestClass().orElse(null);
1✔
148
        Method testMethod = context.getTestMethod().orElse(null);
1✔
149
        Object testInstance = context.getTestInstance().orElse(null);
1✔
150

151
        if (testMethod == null || testInstance == null) {
1!
152
            initContext = new ParamValueInitContext(testInstance, testClass, testMethod,
×
153
                    "@Test failed to acquire instance of test class, or target method");
154
            return;
×
155
        }
156

157
        TestRun.enterNoMockingZone();
1✔
158

159
        try {
160
            savePointForTestMethod = new SavePoint();
1✔
161
            createInstancesForTestedFieldsFromBaseClasses(testInstance);
1✔
162
            initContext = new ParamValueInitContext(testInstance, testClass, testMethod, null);
1✔
163
            parameterValues = createInstancesForAnnotatedParameters(testInstance, testMethod, null);
1✔
164
            createInstancesForTestedFields(testInstance);
1✔
165
        } finally {
166
            TestRun.exitNoMockingZone();
1✔
167
        }
168

169
        TestRun.setRunningIndividualTest(testInstance);
1✔
170
    }
1✔
171

172
    @Override
173
    public boolean supportsParameter(@NonNull ParameterContext parameterContext,
174
            @NonNull ExtensionContext extensionContext) {
175
        return parameterContext.isAnnotated(Tested.class) || parameterContext.isAnnotated(Mocked.class)
1✔
176
                || parameterContext.isAnnotated(Injectable.class) || parameterContext.isAnnotated(Capturing.class);
1!
177
    }
178

179
    @Override
180
    public Object resolveParameter(@NonNull ParameterContext parameterContext,
181
            @NonNull ExtensionContext extensionContext) {
182
        int parameterIndex = parameterContext.getIndex();
1✔
183
        if (parameterValues == null) {
1!
184
            String warning = initContext.warning;
×
185
            StringBuilder exceptionMessage = new StringBuilder(
×
186
                    "JMockit failed to provide parameters to JUnit 5 ParameterResolver.");
187
            if (warning != null) {
×
188
                exceptionMessage.append("\nAdditional info: ").append(warning);
×
189
            }
190
            exceptionMessage.append("\n - Class: ").append(initContext.displayClass());
×
191
            exceptionMessage.append("\n - Method: ").append(initContext.displayMethod());
×
192
            throw new IllegalStateException(exceptionMessage.toString());
×
193
        }
194
        return parameterValues[parameterIndex];
1✔
195
    }
196

197
    @Override
198
    public void handleTestExecutionException(@NonNull ExtensionContext context, @NonNull Throwable throwable)
199
            throws Throwable {
200
        thrownByTest = throwable;
×
201
        throw throwable;
×
202
    }
203

204
    @Override
205
    public void afterTestExecution(@NonNull ExtensionContext context) {
206
        if (savePointForTestMethod == null) {
1!
207
            return;
×
208
        }
209

210
        TestRun.enterNoMockingZone();
1✔
211

212
        try {
213
            savePointForTestMethod.rollback();
1✔
214
            savePointForTestMethod = null;
1✔
215

216
            if (thrownByTest != null) {
1!
217
                filterStackTrace(thrownByTest);
×
218
            }
219

220
            Error expectationsFailure = RecordAndReplayExecution.endCurrentReplayIfAny();
1✔
221
            clearTestedObjectsIfAny();
1✔
222

223
            if (expectationsFailure != null) {
1!
224
                filterStackTrace(expectationsFailure);
×
225
                throw expectationsFailure;
×
226
            }
227
        } finally {
228
            TestRun.finishCurrentTestExecution();
1✔
229
            TestRun.exitNoMockingZone();
1✔
230
        }
231
    }
1✔
232

233
    @Override
234
    public void afterEach(@NonNull ExtensionContext context) {
235
        if (savePointForTest != null) {
1!
236
            savePointForTest.rollback();
1✔
237
            savePointForTest = null;
1✔
238
        }
239
    }
1✔
240

241
    @Override
242
    public void afterAll(@NonNull ExtensionContext context) {
243
        if (savePointForTestClass != null && isRegularTestClass(context)) {
1!
244
            savePointForTestClass.rollback();
1✔
245
            savePointForTestClass = null;
1✔
246

247
            clearFieldTypeRedefinitions();
1✔
248
            TestRun.setCurrentTestClass(null);
1✔
249
        }
250
    }
1✔
251

252
    private static class ParamValueInitContext {
253
        private final Object instance;
254
        private final Class<?> clazz;
255
        private final Method method;
256
        private final String warning;
257

258
        ParamValueInitContext(Object instance, Class<?> clazz, Method method, String warning) {
1✔
259
            this.instance = instance;
1✔
260
            this.clazz = clazz;
1✔
261
            this.method = method;
1✔
262
            this.warning = warning;
1✔
263
        }
1✔
264

265
        boolean isBeforeAllMethod() {
266
            return method != null && method.getDeclaredAnnotation(BeforeAll.class) != null;
×
267
        }
268

269
        boolean isBeforeEachMethod() {
270
            return method != null && method.getDeclaredAnnotation(BeforeEach.class) != null;
×
271
        }
272

273
        String displayClass() {
274
            return clazz == null ? "<no class reference>" : clazz.getName();
×
275
        }
276

277
        String displayMethod() {
278
            if (method == null) {
×
279
                return "<no method reference>";
×
280
            }
281
            String methodPrefix = isBeforeAllMethod() ? "@BeforeAll " : isBeforeEachMethod() ? "@BeforeEach " : "";
×
282
            String args = Arrays.stream(method.getParameterTypes()).map(Class::getName)
×
283
                    .collect(Collectors.joining(", "));
×
284
            return methodPrefix + method.getName() + "(" + args + ")";
×
285
        }
286

287
        @Override
288
        public String toString() {
289
            return "ParamContext{hasInstance=" + (instance == null ? "false" : "true") + ", class=" + clazz
×
290
                    + ", method=" + method + ", warning=" + warning + "}";
291
        }
292
    }
293
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc