• 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

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

8
import static java.lang.reflect.Modifier.isAbstract;
9

10
import static mockit.internal.util.GeneratedClasses.isGeneratedImplementationClassName;
11

12
import edu.umd.cs.findbugs.annotations.NonNull;
13
import edu.umd.cs.findbugs.annotations.Nullable;
14

15
import java.lang.reflect.ParameterizedType;
16
import java.lang.reflect.Proxy;
17
import java.lang.reflect.Type;
18
import java.lang.reflect.TypeVariable;
19

20
import mockit.internal.classGeneration.ConcreteSubclass;
21
import mockit.internal.faking.CaptureOfFakedImplementations;
22
import mockit.internal.faking.FakeClassSetup;
23
import mockit.internal.faking.FakeClasses;
24
import mockit.internal.faking.FakedImplementationClass;
25
import mockit.internal.reflection.ConstructorReflection;
26
import mockit.internal.reflection.MockInvocationHandler;
27
import mockit.internal.startup.Startup;
28
import mockit.internal.state.TestRun;
29

30
/**
31
 * A base class used in the creation of a <em>fake</em> for an <em>external</em> type, which is usually a class from
32
 * some library or component used from the <em>internal</em> codebase of the system under test (SUT). Such fake classes
33
 * can be used as <em>fake implementations</em> for use in unit or integration tests. For example:
34
 *
35
 * <pre>{@code
36
 * public final class FakeSystem <strong>extends MockUp&lt;System></strong> {
37
 *    <strong>&#64;Mock</strong> public static long nanoTime() { return 123L; }
38
 * }
39
 * }</pre>
40
 *
41
 * One or more <em>fake methods</em> annotated {@linkplain Mock as such} must be defined in the concrete subclass. Each
42
 * <code>@Mock</code> method should have a matching method or constructor in the faked class. At runtime, the execution
43
 * of a faked method/constructor will get redirected to the corresponding fake method.
44
 * <p>
45
 * When the type to be faked is specified indirectly through a {@linkplain TypeVariable type variable}, then that type
46
 * is taken as a <em>base</em> type whose concrete implementation classes should <em>also</em> get faked. Example:
47
 *
48
 * <pre>{@code
49
 * &#64;Test
50
 * public &lt;<strong>BC extends SomeBaseClass</strong>> void someTest() {
51
 *     new MockUp&lt;<strong>BC</strong>>() {
52
 *        &#64;Mock int someMethod(int i) { return i + 1; }
53
 *     };
54
 *
55
 *     int i = new AConcreteSubclass().someMethod(1);
56
 *     assertEquals(2, i);
57
 * }
58
 * }</pre>
59
 *
60
 * @param <T>
61
 *            specifies the type to be faked; if a type variable is used, then all implementation classes extending or
62
 *            implementing that base type are also faked; if the type argument itself is a parameterized type, then only
63
 *            its raw type is considered
64
 *
65
 * @see #MockUp()
66
 * @see #MockUp(Class)
67
 * @see #MockUp(Object)
68
 * @see #getMockInstance()
69
 * @see #onTearDown()
70
 * @see #targetType
71
 * @see <a href="http://jmockit.github.io/tutorial/Faking.html#setUp" target="tutorial">Tutorial</a>
72
 */
73
public abstract class MockUp<T> {
74
    static {
75
        Startup.verifyInitialization();
1✔
76
    }
1✔
77

78
    /**
79
     * Holds the class or generic type targeted by this fake instance.
80
     */
81
    protected final Type targetType;
82

83
    @Nullable
84
    private final Class<?> mockedClass;
85
    @Nullable
86
    private T mockInstance;
87
    @Nullable
88
    private T invokedInstance;
89

90
    /**
91
     * Applies the {@linkplain Mock fake methods} defined in the concrete subclass to the class or interface specified
92
     * through the type parameter.
93
     *
94
     * @see #MockUp(Class)
95
     * @see #MockUp(Object)
96
     */
97
    protected MockUp() {
1✔
98
        MockUp<?> previousMockUp = findPreviouslyFakedClassIfMockUpAlreadyApplied();
1✔
99

100
        if (previousMockUp != null) {
1✔
101
            targetType = previousMockUp.targetType;
1✔
102
            mockedClass = previousMockUp.mockedClass;
1✔
103
            return;
1✔
104
        }
105

106
        targetType = getTypeToFake();
1✔
107
        Class<T> classToMock = null;
1✔
108

109
        if (targetType instanceof Class<?>) {
1✔
110
            // noinspection unchecked
111
            classToMock = (Class<T>) targetType;
1✔
112
        } else if (targetType instanceof ParameterizedType) {
1✔
113
            ParameterizedType parameterizedType = (ParameterizedType) targetType;
1✔
114
            // noinspection unchecked
115
            classToMock = (Class<T>) parameterizedType.getRawType();
1✔
116
        }
117

118
        if (classToMock != null) {
1✔
119
            mockedClass = redefineClassOrImplementInterface(classToMock);
1✔
120
        } else {
121
            Type[] typesToMock = ((TypeVariable<?>) targetType).getBounds();
1✔
122

123
            mockedClass = typesToMock.length > 1
1✔
124
                    ? new FakedImplementationClass<T>(this).createImplementation(typesToMock)
×
125
                    : new CaptureOfFakedImplementations(this, typesToMock[0]).apply();
1✔
126
        }
127
    }
1✔
128

129
    @Nullable
130
    private MockUp<?> findPreviouslyFakedClassIfMockUpAlreadyApplied() {
131
        FakeClasses mockClasses = TestRun.getFakeClasses();
1✔
132
        FakeClasses.MockUpInstances mockUpInstances = mockClasses.findPreviouslyAppliedMockUps(this);
1✔
133

134
        if (mockUpInstances != null && mockUpInstances.hasMockUpsForSingleInstances()) {
1✔
135
            return mockUpInstances.initialMockUp;
1✔
136
        }
137

138
        return null;
1✔
139
    }
140

141
    /**
142
     * Gets the type to fake.
143
     *
144
     * @return the type to fake
145
     */
146
    @NonNull
147
    private Type getTypeToFake() {
148
        Class<?> currentClass = getClass();
1✔
149

150
        do {
151
            Type superclass = currentClass.getGenericSuperclass();
1✔
152

153
            if (superclass instanceof ParameterizedType) {
1✔
154
                return ((ParameterizedType) superclass).getActualTypeArguments()[0];
1✔
155
            }
156

157
            if (superclass == MockUp.class) {
1✔
158
                throw new IllegalArgumentException("No target type");
1✔
159
            }
160

161
            currentClass = (Class<?>) superclass;
1✔
162
        } while (true);
1✔
163
    }
164

165
    @NonNull
166
    private Class<?> redefineClassOrImplementInterface(@NonNull Class<T> classToMock) {
167
        if (classToMock.isInterface()) {
1✔
168
            return createInstanceOfMockedImplementationClass(classToMock, targetType);
1✔
169
        }
170

171
        Class<T> realClass = classToMock;
1✔
172

173
        if (isAbstract(classToMock.getModifiers())) {
1✔
174
            classToMock = new ConcreteSubclass<T>(classToMock).generateClass();
1✔
175
        }
176

177
        redefineMethods(realClass, classToMock, targetType);
1✔
178
        return classToMock;
1✔
179
    }
180

181
    @NonNull
182
    private Class<T> createInstanceOfMockedImplementationClass(@NonNull Class<T> classToMock,
183
            @Nullable Type typeToMock) {
184
        return new FakedImplementationClass<T>(this).createImplementation(classToMock, typeToMock);
1✔
185
    }
186

187
    private void redefineMethods(@NonNull Class<T> realClass, @NonNull Class<T> classToMock,
188
            @Nullable Type genericMockedType) {
189
        new FakeClassSetup(realClass, classToMock, genericMockedType, this).redefineMethods();
1✔
190
    }
1✔
191

192
    /**
193
     * Applies the {@linkplain Mock mock methods} defined in the mock-up subclass to the given class/interface.
194
     * <p>
195
     * In most cases, the constructor with no parameters can be used. This variation should be used only when the type
196
     * to be faked is not accessible or known from the test code.
197
     *
198
     * @param targetClass
199
     *            the target class
200
     *
201
     * @see #MockUp()
202
     * @see #MockUp(Object)
203
     */
204
    protected MockUp(Class<?> targetClass) {
1✔
205
        targetType = targetClass;
1✔
206
        MockUp<?> previousMockUp = findPreviouslyFakedClassIfMockUpAlreadyApplied();
1✔
207

208
        if (previousMockUp != null) {
1✔
209
            mockedClass = previousMockUp.mockedClass;
1✔
210
            return;
1✔
211
        }
212

213
        if (targetClass.isInterface()) {
1✔
214
            // noinspection unchecked
215
            mockedClass = createInstanceOfMockedImplementationClass((Class<T>) targetClass, targetClass);
1✔
216
        } else {
217
            mockedClass = targetClass;
1✔
218
            // noinspection unchecked
219
            Class<T> realClass = (Class<T>) targetClass;
1✔
220
            redefineMethods(realClass, realClass, null);
1✔
221
            mockInstance = null;
1✔
222
        }
223
    }
1✔
224

225
    /**
226
     * Applies the {@linkplain Mock mock methods} defined in the mock-up subclass to the type specified through the type
227
     * parameter, but only affecting the given instance.
228
     * <p>
229
     * In most cases, the constructor with no parameters should be adequate. This variation can be used when mock data
230
     * or behavior is desired only for a particular instance, with other instances remaining unaffected; or when
231
     * multiple mock-up objects carrying different states are desired, with one mock-up instance per real instance.
232
     * <p>
233
     * If {@link #getMockInstance()} later gets called on this mock-up instance, it will return the instance that was
234
     * given here.
235
     *
236
     * @param targetInstance
237
     *            a real instance of the type to be faked, meant to be the only one of that type that should be affected
238
     *            by this mock-up instance
239
     *
240
     * @see #MockUp()
241
     * @see #MockUp(Class)
242
     */
243
    protected MockUp(T targetInstance) {
1✔
244
        MockUp<?> previousMockUp = findPreviouslyFakedClassIfMockUpAlreadyApplied();
1✔
245

246
        if (previousMockUp != null) {
1✔
247
            targetType = previousMockUp.targetType;
1✔
248
            mockedClass = previousMockUp.mockedClass;
1✔
249
            setMockInstance(targetInstance);
1✔
250
            return;
1✔
251
        }
252

253
        @SuppressWarnings("unchecked")
254
        Class<T> classToMock = (Class<T>) targetInstance.getClass();
1✔
255
        targetType = classToMock;
1✔
256
        mockedClass = classToMock;
1✔
257
        redefineMethods(classToMock, classToMock, classToMock);
1✔
258

259
        setMockInstance(targetInstance);
1✔
260
    }
1✔
261

262
    private void setMockInstance(@NonNull T mockInstance) {
263
        TestRun.getFakeClasses().addFake(this, mockInstance);
1✔
264
        this.mockInstance = mockInstance;
1✔
265
    }
1✔
266

267
    /**
268
     * Returns the mock instance exclusively associated with this mock-up instance. If the mocked type was an interface,
269
     * then said instance is the one that was automatically created when the mock-up was applied. If it was a class, and
270
     * no such instance is currently associated with this (stateful) mock-up object, then a new <em>uninitialized</em>
271
     * instance of the faked class is created and returned, becoming associated with the mock-up. If a regular
272
     * <em>initialized</em> instance was desired, then the {@link #MockUp(Object)} constructor should have been used
273
     * instead.
274
     * <p>
275
     * In any case, for a given mock-up instance this method will always return the same mock instance.
276
     *
277
     * @return the mock instance
278
     *
279
     * @see <a href="http://jmockit.github.io/tutorial/Faking.html#interfaces" target="tutorial">Tutorial</a>
280
     */
281
    public final T getMockInstance() {
282
        if (invokedInstance == Void.class) {
1!
283
            return null;
×
284
        }
285

286
        if (invokedInstance != null) {
1✔
287
            return invokedInstance;
1✔
288
        }
289

290
        if (mockInstance == null && mockedClass != null) {
1!
291
            @SuppressWarnings("unchecked")
292
            T newInstance = (T) createMockInstance(mockedClass);
1✔
293
            setMockInstance(newInstance);
1✔
294
        }
295

296
        return mockInstance;
1✔
297
    }
298

299
    @NonNull
300
    private Object createMockInstance(@NonNull Class<?> mockedClass) {
301
        String mockedClassName = mockedClass.getName();
1✔
302

303
        if (isGeneratedImplementationClassName(mockedClassName)) {
1✔
304
            return ConstructorReflection.newInstanceUsingPublicDefaultConstructor(mockedClass);
1✔
305
        }
306

307
        if (Proxy.isProxyClass(mockedClass)) {
1✔
308
            return MockInvocationHandler.newMockedInstance(mockedClass);
1✔
309
        }
310

311
        return ConstructorReflection.newUninitializedInstance(mockedClass);
1✔
312
    }
313

314
    /**
315
     * An empty method that can be overridden in a mock-up subclass that wants to be notified whenever the mock-up is
316
     * automatically torn down. Tear down happens when the mock-up goes out of scope: at the end of the test when
317
     * applied inside a test, at the end of the test class when applied before the test class, or at the end of the test
318
     * run when applied through the "<code>mockups</code>" system property.
319
     * <p>
320
     * By default, this method does nothing.
321
     */
322
    protected void onTearDown() {
323
    }
1✔
324
}
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