• 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

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

8
import static mockit.internal.reflection.FieldReflection.getFieldValue;
9

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

13
import java.lang.instrument.ClassDefinition;
14
import java.util.ArrayList;
15
import java.util.Collection;
16
import java.util.HashMap;
17
import java.util.List;
18
import java.util.Map;
19

20
import mockit.asm.classes.ClassReader;
21
import mockit.asm.types.JavaType;
22
import mockit.internal.BaseClassModifier;
23
import mockit.internal.capturing.CaptureOfImplementations;
24
import mockit.internal.startup.Startup;
25
import mockit.internal.state.MockFixture;
26
import mockit.internal.state.TestRun;
27
import mockit.internal.util.Utilities;
28

29
public class CaptureOfNewInstances extends CaptureOfImplementations<MockedType> {
30
    protected static final class Capture {
31
        @NonNull
32
        final MockedType typeMetadata;
33
        @Nullable
34
        private Object originalMockInstance;
35
        @NonNull
36
        private final List<Object> instancesCaptured;
37

38
        private Capture(@NonNull MockedType typeMetadata, @Nullable Object originalMockInstance) {
1✔
39
            this.typeMetadata = typeMetadata;
1✔
40
            this.originalMockInstance = originalMockInstance;
1✔
41
            instancesCaptured = new ArrayList<>(4);
1✔
42
        }
1✔
43

44
        private boolean isInstanceAlreadyCaptured(@NonNull Object mock) {
45
            return Utilities.containsReference(instancesCaptured, mock);
1✔
46
        }
47

48
        private boolean captureInstance(@Nullable Object fieldOwner, @NonNull Object instance) {
49
            if (instancesCaptured.size() < typeMetadata.getMaxInstancesToCapture()) {
1!
50
                if (fieldOwner != null && typeMetadata.field != null && originalMockInstance == null) {
1!
51
                    originalMockInstance = getFieldValue(typeMetadata.field, fieldOwner);
1✔
52
                }
53

54
                instancesCaptured.add(instance);
1✔
55
                return true;
1✔
56
            }
57

58
            return false;
×
59
        }
60

61
        void reset() {
62
            originalMockInstance = null;
1✔
63
            instancesCaptured.clear();
1✔
64
        }
1✔
65
    }
66

67
    @NonNull
68
    private final Map<Class<?>, List<Capture>> baseTypeToCaptures;
69

70
    CaptureOfNewInstances() {
1✔
71
        baseTypeToCaptures = new HashMap<>();
1✔
72
    }
1✔
73

74
    @NonNull
75
    protected final Collection<List<Capture>> getCapturesForAllBaseTypes() {
76
        return baseTypeToCaptures.values();
1✔
77
    }
78

79
    @NonNull
80
    @Override
81
    protected BaseClassModifier createModifier(@Nullable ClassLoader cl, @NonNull ClassReader cr,
82
            @NonNull Class<?> baseType, @Nullable MockedType typeMetadata) {
83
        MockedClassModifier modifier = new MockedClassModifier(cl, cr, typeMetadata);
1✔
84
        String baseTypeDesc = JavaType.getInternalName(baseType);
1✔
85
        modifier.setClassNameForCapturedInstanceMethods(baseTypeDesc);
1✔
86
        return modifier;
1✔
87
    }
88

89
    @Override
90
    protected void redefineClass(@NonNull Class<?> realClass, @NonNull byte[] modifiedClass) {
91
        ClassDefinition newClassDefinition = new ClassDefinition(realClass, modifiedClass);
1✔
92
        Startup.redefineMethods(newClassDefinition);
1✔
93

94
        MockFixture mockFixture = TestRun.mockFixture();
1✔
95
        mockFixture.addRedefinedClass(newClassDefinition);
1✔
96
        mockFixture.registerMockedClass(realClass);
1✔
97
    }
1✔
98

99
    void registerCaptureOfNewInstances(@NonNull MockedType typeMetadata, @Nullable Object mockInstance) {
100
        Class<?> baseType = typeMetadata.getClassType();
1✔
101

102
        if (!typeMetadata.isFinalFieldOrParameter()) {
1✔
103
            makeSureAllSubtypesAreModified(typeMetadata);
1✔
104
        }
105

106
        List<Capture> captures = baseTypeToCaptures.computeIfAbsent(baseType, k -> new ArrayList<>());
1✔
107
        captures.add(new Capture(typeMetadata, mockInstance));
1✔
108
    }
1✔
109

110
    void makeSureAllSubtypesAreModified(@NonNull MockedType typeMetadata) {
111
        Class<?> baseType = typeMetadata.getClassType();
1✔
112
        makeSureAllSubtypesAreModified(baseType, typeMetadata.fieldFromTestClass, typeMetadata);
1✔
113
    }
1✔
114

115
    public boolean captureNewInstance(@Nullable Object fieldOwner, @NonNull Object mock) {
116
        Class<?> mockedClass = mock.getClass();
1✔
117
        List<Capture> captures = baseTypeToCaptures.get(mockedClass);
1✔
118
        boolean constructorModifiedForCaptureOnly = captures == null;
1!
119

120
        if (constructorModifiedForCaptureOnly) {
1!
121
            captures = findCaptures(mockedClass);
1✔
122

123
            if (captures == null) {
1✔
124
                return false;
1✔
125
            }
126
        }
127

128
        Capture captureFound = findCapture(fieldOwner, mock, captures);
1✔
129

130
        if (captureFound != null) {
1✔
131
            if (captureFound.typeMetadata.injectable) {
1!
132
                TestRun.getExecutingTest().addCapturedInstanceForInjectableMock(captureFound.originalMockInstance,
×
133
                        mock);
134
                constructorModifiedForCaptureOnly = true;
×
135
            } else {
136
                TestRun.getExecutingTest().addCapturedInstance(captureFound.originalMockInstance, mock);
1✔
137
            }
138
        }
139

140
        return constructorModifiedForCaptureOnly;
1✔
141
    }
142

143
    @Nullable
144
    private List<Capture> findCaptures(@NonNull Class<?> mockedClass) {
145
        Class<?>[] interfaces = mockedClass.getInterfaces();
1✔
146

147
        for (Class<?> anInterface : interfaces) {
1✔
148
            List<Capture> found = baseTypeToCaptures.get(anInterface);
1✔
149

150
            if (found != null) {
1✔
151
                return found;
1✔
152
            }
153
        }
154

155
        Class<?> superclass = mockedClass.getSuperclass();
1✔
156

157
        if (superclass == Object.class) {
1✔
158
            return null;
1✔
159
        }
160

161
        List<Capture> found = baseTypeToCaptures.get(superclass);
1✔
162

163
        return found != null ? found : findCaptures(superclass);
1✔
164
    }
165

166
    @Nullable
167
    private static Capture findCapture(@Nullable Object fieldOwner, @NonNull Object mock,
168
            @NonNull List<Capture> captures) {
169
        for (Capture capture : captures) {
1!
170
            if (capture.isInstanceAlreadyCaptured(mock)) {
1✔
171
                break;
1✔
172
            } else if (capture.captureInstance(fieldOwner, mock)) {
1!
173
                return capture;
1✔
174
            }
175
        }
×
176

177
        return null;
1✔
178
    }
179

180
    public void cleanUp() {
181
        baseTypeToCaptures.clear();
1✔
182
    }
1✔
183
}
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