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

hazendaz / jmockit1 / 461

08 Nov 2025 01:26AM UTC coverage: 72.263% (+0.03%) from 72.238%
461

push

github

web-flow
Merge pull request #407 from hazendaz/junit5-ext

Ensure target is an instance of the test class for which this FieldTy…

5679 of 8364 branches covered (67.9%)

Branch coverage included in aggregate %.

2 of 3 new or added lines in 1 file covered. (66.67%)

11943 of 16022 relevant lines covered (74.54%)

0.75 hits per line

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

88.97
/main/src/main/java/mockit/internal/expectations/mocking/FieldTypeRedefinitions.java
1
/*
2
 * Copyright (c) 2006 JMockit developers
3
 * This file is subject to the terms of the MIT license (see LICENSE.txt).
4
 */
5
package mockit.internal.expectations.mocking;
6

7
import static java.lang.reflect.Modifier.isFinal;
8

9
import edu.umd.cs.findbugs.annotations.NonNull;
10

11
import java.lang.reflect.Field;
12
import java.util.ArrayList;
13
import java.util.HashMap;
14
import java.util.List;
15
import java.util.Map;
16
import java.util.Map.Entry;
17

18
import mockit.asm.jvmConstants.Access;
19
import mockit.internal.reflection.FieldReflection;
20
import mockit.internal.state.TestRun;
21
import mockit.internal.util.StackTrace;
22

23
@SuppressWarnings("UnnecessaryFullyQualifiedName")
1✔
24
public final class FieldTypeRedefinitions extends TypeRedefinitions {
25
    private static final int FIELD_ACCESS_MASK = Access.SYNTHETIC + Access.STATIC;
26

27
    @NonNull
28
    private final Map<MockedType, InstanceFactory> mockInstanceFactories;
29
    @NonNull
30
    private final List<MockedType> mockFieldsNotSet;
31
    @NonNull
32
    private final Class<?> testClass;
33

34
    public FieldTypeRedefinitions(@NonNull Class<?> testClass) {
1✔
35
        this.testClass = testClass;
1✔
36
        mockInstanceFactories = new HashMap<>();
1✔
37
        mockFieldsNotSet = new ArrayList<>();
1✔
38

39
        TestRun.enterNoMockingZone();
1✔
40

41
        try {
42
            redefineFieldTypes(testClass);
1✔
43
        } finally {
44
            TestRun.exitNoMockingZone();
1✔
45
        }
46
    }
1✔
47

48
    private void redefineFieldTypes(@NonNull Class<?> classWithMockFields) {
49
        Class<?> superClass = classWithMockFields.getSuperclass();
1✔
50

51
        if (superClass != null && superClass != Object.class && superClass != mockit.Expectations.class) {
1!
52
            redefineFieldTypes(superClass);
1✔
53
        }
54

55
        Field[] fields = classWithMockFields.getDeclaredFields();
1✔
56

57
        for (Field candidateField : fields) {
1✔
58
            int fieldModifiers = candidateField.getModifiers();
1✔
59

60
            if ((fieldModifiers & FIELD_ACCESS_MASK) == 0) {
1✔
61
                redefineFieldType(candidateField, fieldModifiers);
1✔
62
            }
63
        }
64
    }
1✔
65

66
    private void redefineFieldType(@NonNull Field field, int modifiers) {
67
        MockedType mockedType = new MockedType(field);
1✔
68

69
        if (mockedType.isMockableType()) {
1✔
70
            boolean partialMocking = field.isAnnotationPresent(mockit.Tested.class);
1✔
71
            boolean needsValueToSet = !isFinal(modifiers) && !partialMocking;
1✔
72

73
            redefineFieldType(mockedType, partialMocking, needsValueToSet);
1✔
74

75
            if (!partialMocking) {
1✔
76
                registerCaptureOfNewInstances(mockedType);
1✔
77
            }
78
        }
79
    }
1✔
80

81
    private void redefineFieldType(@NonNull MockedType mockedType, boolean partialMocking, boolean needsValueToSet) {
82
        FieldTypeRedefinition typeRedefinition = new FieldTypeRedefinition(mockedType);
1✔
83
        boolean redefined;
84

85
        if (needsValueToSet) {
1✔
86
            InstanceFactory factory = typeRedefinition.redefineType();
1✔
87
            redefined = factory != null;
1!
88

89
            if (redefined) {
1!
90
                mockInstanceFactories.put(mockedType, factory);
1✔
91
            }
92
        } else {
1✔
93
            if (partialMocking) {
1✔
94
                redefined = typeRedefinition.redefineTypeForTestedField();
1✔
95
            } else {
96
                redefined = typeRedefinition.redefineTypeForFinalField();
1✔
97
            }
98

99
            if (redefined) {
1!
100
                mockFieldsNotSet.add(mockedType);
1✔
101
            }
102
        }
103

104
        if (redefined) {
1!
105
            addTargetClass(mockedType);
1✔
106
        }
107
    }
1✔
108

109
    private void registerCaptureOfNewInstances(@NonNull MockedType mockedType) {
110
        if (mockedType.getMaxInstancesToCapture() > 0) {
1✔
111
            if (captureOfNewInstances == null) {
1✔
112
                captureOfNewInstances = new CaptureOfNewInstancesForFields();
1✔
113
            }
114

115
            captureOfNewInstances.registerCaptureOfNewInstances(mockedType, null);
1✔
116
        }
117
    }
1✔
118

119
    public void assignNewInstancesToMockFields(@NonNull Object target) {
120
        // Ensure target is an instance of the test class for which this FieldTypeRedefinitions was created
121
        if (target == null || !testClass.isInstance(target)) {
1!
122
            // Skip assignment if target is not the expected test class instance
NEW
123
            return;
×
124
        }
125
        TestRun.getExecutingTest().clearRegularAndInjectableMocks();
1✔
126
        createAndAssignNewInstances(target);
1✔
127
        obtainAndRegisterInstancesOfFieldsNotSet(target);
1✔
128
    }
1✔
129

130
    private void createAndAssignNewInstances(@NonNull Object target) {
131
        for (Entry<MockedType, InstanceFactory> metadataAndFactory : mockInstanceFactories.entrySet()) {
1✔
132
            MockedType mockedType = metadataAndFactory.getKey();
1✔
133
            InstanceFactory instanceFactory = metadataAndFactory.getValue();
1✔
134

135
            Object mock = assignNewInstanceToMockField(target, mockedType, instanceFactory);
1✔
136
            registerMock(mockedType, mock);
1✔
137
        }
1✔
138
    }
1✔
139

140
    @NonNull
141
    private Object assignNewInstanceToMockField(@NonNull Object target, @NonNull MockedType mockedType,
142
            @NonNull InstanceFactory instanceFactory) {
143
        Field mockField = mockedType.field;
1✔
144
        assert mockField != null;
1!
145
        Object mock = FieldReflection.getFieldValue(mockField, target);
1✔
146

147
        if (mock == null) {
1✔
148
            try {
149
                mock = instanceFactory.create();
1✔
150
            } catch (NoClassDefFoundError | ExceptionInInitializerError e) {
×
151
                StackTrace.filterStackTrace(e);
×
152
                e.printStackTrace();
×
153
                throw e;
×
154
            }
1✔
155

156
            FieldReflection.setFieldValue(mockField, target, mock);
1✔
157

158
            if (mockedType.getMaxInstancesToCapture() > 0) {
1✔
159
                assert captureOfNewInstances != null;
1!
160
                CaptureOfNewInstancesForFields capture = (CaptureOfNewInstancesForFields) captureOfNewInstances;
1✔
161
                capture.resetCaptureCount(mockField);
1✔
162
            }
163
        }
164

165
        return mock;
1✔
166
    }
167

168
    private void obtainAndRegisterInstancesOfFieldsNotSet(@NonNull Object target) {
169
        for (MockedType metadata : mockFieldsNotSet) {
1✔
170
            assert metadata.field != null;
1!
171
            Object mock = FieldReflection.getFieldValue(metadata.field, target);
1✔
172

173
            if (mock != null) {
1✔
174
                registerMock(metadata, mock);
1✔
175
            }
176
        }
1✔
177
    }
1✔
178

179
    /**
180
     * Returns true iff the mock instance concrete class is not mocked in some test, i.e. it's a class which only
181
     * appears in the code under test.
182
     */
183
    public boolean captureNewInstanceForApplicableMockField(@NonNull Object mock) {
184
        if (captureOfNewInstances == null) {
1✔
185
            return false;
1✔
186
        }
187

188
        Object fieldOwner = TestRun.getCurrentTestInstance();
1✔
189
        return captureOfNewInstances.captureNewInstance(fieldOwner, mock);
1✔
190
    }
191

192
    @Override
193
    public void cleanUp() {
194
        TestRun.getExecutingTest().getCascadingTypes().clear();
1✔
195
        super.cleanUp();
1✔
196
    }
1✔
197
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc