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

hazendaz / jmockit1 / 398

29 Oct 2025 01:58PM UTC coverage: 72.206% (-0.02%) from 72.226%
398

push

github

web-flow
Merge pull request #395 from hazendaz/develop

Migrate jmockit tests away from javax to jakarta

5683 of 8360 branches covered (67.98%)

Branch coverage included in aggregate %.

11946 of 16055 relevant lines covered (74.41%)

0.74 hits per line

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

92.74
/main/src/main/java/mockit/internal/injection/Injector.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.injection;
6

7
import static java.lang.reflect.Modifier.isFinal;
8
import static java.lang.reflect.Modifier.isStatic;
9
import static java.lang.reflect.Modifier.isVolatile;
10
import static java.util.regex.Pattern.compile;
11

12
import static mockit.internal.injection.InjectionPoint.JAKARTA_PERSISTENCE_UNIT_CLASS;
13
import static mockit.internal.injection.InjectionPoint.JAVAX_PERSISTENCE_UNIT_CLASS;
14
import static mockit.internal.injection.InjectionPoint.convertToLegalJavaIdentifierIfNeeded;
15
import static mockit.internal.injection.InjectionPoint.getQualifiedName;
16
import static mockit.internal.injection.InjectionPoint.isJakartaServlet;
17
import static mockit.internal.injection.InjectionPoint.isJavaxServlet;
18
import static mockit.internal.injection.InjectionPoint.kindOfInjectionPoint;
19
import static mockit.internal.injection.InjectionPoint.wrapInProviderIfNeeded;
20
import static mockit.internal.injection.InjectionProvider.NULL;
21

22
import edu.umd.cs.findbugs.annotations.NonNull;
23
import edu.umd.cs.findbugs.annotations.Nullable;
24

25
import java.lang.reflect.Field;
26
import java.lang.reflect.Type;
27
import java.lang.reflect.TypeVariable;
28
import java.util.ArrayList;
29
import java.util.List;
30
import java.util.regex.Pattern;
31

32
import mockit.internal.injection.InjectionPoint.KindOfInjectionPoint;
33
import mockit.internal.injection.field.FieldToInject;
34
import mockit.internal.injection.full.FullInjection;
35
import mockit.internal.reflection.FieldReflection;
36
import mockit.internal.util.DefaultValues;
37

38
public class Injector {
39
    private static final Pattern TYPE_NAME = compile("class |interface |java\\.lang\\.");
1✔
40

41
    @NonNull
42
    protected final InjectionState injectionState;
43
    @Nullable
44
    protected final FullInjection fullInjection;
45

46
    protected Injector(@NonNull InjectionState state, @Nullable FullInjection fullInjection) {
1✔
47
        injectionState = state;
1✔
48
        this.fullInjection = fullInjection;
1✔
49
    }
1✔
50

51
    @NonNull
52
    static List<Field> findAllTargetInstanceFieldsInTestedClassHierarchy(@NonNull Class<?> actualTestedClass,
53
            @NonNull TestedClass testedClass) {
54
        List<Field> targetFields = new ArrayList<>();
1✔
55
        Class<?> classWithFields = actualTestedClass;
1✔
56

57
        do {
58
            addEligibleFields(targetFields, classWithFields);
1✔
59
            classWithFields = classWithFields.getSuperclass();
1✔
60
        } while (testedClass.isClassFromSameModuleOrSystemAsTestedClass(classWithFields)
1✔
61
                || isJakartaServlet(classWithFields) || isJavaxServlet(classWithFields));
1!
62

63
        return targetFields;
1✔
64
    }
65

66
    private static void addEligibleFields(@NonNull List<Field> targetFields, @NonNull Class<?> classWithFields) {
67
        Field[] fields = classWithFields.getDeclaredFields();
1✔
68

69
        for (Field field : fields) {
1✔
70
            if (isEligibleForInjection(field)) {
1✔
71
                targetFields.add(field);
1✔
72
            }
73
        }
74
    }
1✔
75

76
    private static boolean isEligibleForInjection(@NonNull Field field) {
77
        int modifiers = field.getModifiers();
1✔
78

79
        if (isFinal(modifiers)) {
1✔
80
            return false;
1✔
81
        }
82

83
        if (kindOfInjectionPoint(field) != KindOfInjectionPoint.NotAnnotated) {
1✔
84
            return true;
1✔
85
        }
86

87
        if (JAKARTA_PERSISTENCE_UNIT_CLASS != null
1!
88
                && field.getType().isAnnotationPresent(jakarta.persistence.Entity.class)) {
1✔
89
            return false;
1✔
90
        }
91

92
        if (JAVAX_PERSISTENCE_UNIT_CLASS != null
1!
93
                && field.getType().isAnnotationPresent(javax.persistence.Entity.class)) {
1!
94
            return false;
×
95
        }
96

97
        return !isStatic(modifiers) && !isVolatile(modifiers);
1✔
98
    }
99

100
    public final void fillOutDependenciesRecursively(@NonNull Object dependency, @NonNull TestedClass testedClass) {
101
        Class<?> dependencyClass = dependency.getClass();
1✔
102
        List<Field> targetFields = findAllTargetInstanceFieldsInTestedClassHierarchy(dependencyClass, testedClass);
1✔
103

104
        if (!targetFields.isEmpty()) {
1✔
105
            List<InjectionProvider> currentlyConsumedInjectables = injectionState.injectionProviders
1✔
106
                    .saveConsumedInjectionProviders();
1✔
107
            injectIntoEligibleFields(targetFields, dependency, testedClass);
1✔
108
            injectionState.injectionProviders.restoreConsumedInjectionProviders(currentlyConsumedInjectables);
1✔
109
        }
110
    }
1✔
111

112
    public final void injectIntoEligibleFields(@NonNull List<Field> targetFields, @NonNull Object testedObject,
113
            @NonNull TestedClass testedClass) {
114
        for (Field field : targetFields) {
1✔
115
            if (targetFieldWasNotAssignedByConstructor(testedObject, field)) {
1✔
116
                Object injectableValue = getValueForFieldIfAvailable(targetFields, testedClass, field);
1✔
117

118
                if (injectableValue != null && injectableValue != NULL) {
1✔
119
                    injectableValue = wrapInProviderIfNeeded(field.getGenericType(), injectableValue);
1✔
120
                    FieldReflection.setFieldValue(field, testedObject, injectableValue);
1✔
121
                }
122
            }
123
        }
1✔
124
    }
1✔
125

126
    private static boolean targetFieldWasNotAssignedByConstructor(@NonNull Object testedObject,
127
            @NonNull Field targetField) {
128
        if (kindOfInjectionPoint(targetField) != KindOfInjectionPoint.NotAnnotated) {
1✔
129
            return true;
1✔
130
        }
131

132
        Object fieldValue = FieldReflection.getFieldValue(targetField, testedObject);
1✔
133

134
        if (fieldValue == null) {
1✔
135
            return true;
1✔
136
        }
137

138
        Class<?> fieldType = targetField.getType();
1✔
139

140
        if (!fieldType.isPrimitive()) {
1✔
141
            return false;
1✔
142
        }
143

144
        Object defaultValue = DefaultValues.defaultValueForPrimitiveType(fieldType);
1✔
145

146
        return fieldValue.equals(defaultValue);
1✔
147
    }
148

149
    @Nullable
150
    private Object getValueForFieldIfAvailable(@NonNull List<Field> targetFields, @NonNull TestedClass testedClass,
151
            @NonNull Field targetField) {
152
        @Nullable
153
        String qualifiedFieldName = getQualifiedName(targetField.getDeclaredAnnotations());
1✔
154
        InjectionProvider injectable = findAvailableInjectableIfAny(targetFields, qualifiedFieldName, testedClass,
1✔
155
                targetField);
156

157
        if (injectable != null) {
1✔
158
            return injectionState.getValueToInject(injectable);
1✔
159
        }
160

161
        InjectionProvider fieldToInject = new FieldToInject(targetField);
1✔
162
        Type typeToInject = fieldToInject.getDeclaredType();
1✔
163
        InjectionPoint injectionPoint = new InjectionPoint(typeToInject, fieldToInject.getName(), qualifiedFieldName);
1✔
164
        TestedClass nextTestedClass = typeToInject instanceof TypeVariable<?> ? testedClass
1✔
165
                : new TestedClass(typeToInject, fieldToInject.getClassOfDeclaredType(), testedClass);
1✔
166
        Object testedValue = injectionState.getTestedValue(nextTestedClass, injectionPoint);
1✔
167

168
        if (testedValue != null) {
1✔
169
            return testedValue;
1✔
170
        }
171

172
        if (fullInjection != null) {
1✔
173
            Object newInstance = fullInjection.createOrReuseInstance(nextTestedClass, this, fieldToInject,
1✔
174
                    qualifiedFieldName);
175

176
            if (newInstance != null) {
1✔
177
                return newInstance;
1✔
178
            }
179
        }
180

181
        KindOfInjectionPoint kindOfInjectionPoint = kindOfInjectionPoint(targetField);
1✔
182
        throwExceptionIfUnableToInjectRequiredTargetField(kindOfInjectionPoint, targetField, qualifiedFieldName);
1✔
183
        return null;
1✔
184
    }
185

186
    @Nullable
187
    private InjectionProvider findAvailableInjectableIfAny(@NonNull List<Field> targetFields,
188
            @Nullable String qualifiedTargetFieldName, @NonNull TestedClass testedClass, @NonNull Field targetField) {
189
        KindOfInjectionPoint kindOfInjectionPoint = kindOfInjectionPoint(targetField);
1✔
190
        InjectionProviders injectionProviders = injectionState.injectionProviders;
1✔
191
        injectionProviders.setTypeOfInjectionPoint(targetField.getGenericType(), kindOfInjectionPoint);
1✔
192

193
        if (qualifiedTargetFieldName != null && !qualifiedTargetFieldName.isEmpty()) {
1!
194
            String injectableName = convertToLegalJavaIdentifierIfNeeded(qualifiedTargetFieldName);
1✔
195
            InjectionProvider matchingInjectable = injectionProviders.findInjectableByTypeAndName(injectableName,
1✔
196
                    testedClass);
197

198
            if (matchingInjectable != null) {
1✔
199
                return matchingInjectable;
1✔
200
            }
201
        }
202

203
        String targetFieldName = targetField.getName();
1✔
204

205
        if (withMultipleTargetFieldsOfSameType(targetFields, testedClass, targetField, injectionProviders)) {
1✔
206
            return injectionProviders.findInjectableByTypeAndName(targetFieldName, testedClass);
1✔
207
        }
208

209
        return injectionProviders.getProviderByTypeAndOptionallyName(targetFieldName, testedClass);
1✔
210
    }
211

212
    private static boolean withMultipleTargetFieldsOfSameType(@NonNull List<Field> targetFields,
213
            @NonNull TestedClass testedClass, @NonNull Field targetField,
214
            @NonNull InjectionProviders injectionProviders) {
215
        for (Field anotherTargetField : targetFields) {
1✔
216
            if (anotherTargetField != targetField && injectionProviders
1✔
217
                    .isAssignableToInjectionPoint(anotherTargetField.getGenericType(), testedClass)) {
1✔
218
                return true;
1✔
219
            }
220
        }
1✔
221

222
        return false;
1✔
223
    }
224

225
    private void throwExceptionIfUnableToInjectRequiredTargetField(@NonNull KindOfInjectionPoint kindOfInjectionPoint,
226
            @NonNull Field targetField, @Nullable String qualifiedFieldName) {
227
        if (kindOfInjectionPoint == KindOfInjectionPoint.Required) {
1✔
228
            Type fieldType = targetField.getGenericType();
1✔
229
            String fieldTypeName = fieldType.toString();
1✔
230
            fieldTypeName = TYPE_NAME.matcher(fieldTypeName).replaceAll("");
1✔
231
            String kindOfInjectable = "@Tested or @Injectable";
1✔
232

233
            if (fullInjection != null) {
1!
234
                if (targetField.getType().isInterface()) {
×
235
                    kindOfInjectable = "@Tested instance of an implementation class";
×
236
                } else {
237
                    kindOfInjectable = "@Tested object";
×
238
                }
239
            }
240

241
            throw new IllegalStateException("Missing " + kindOfInjectable + " for field " + fieldTypeName + ' '
1✔
242
                    + targetField.getName() + (qualifiedFieldName == null ? "" : " (\"" + qualifiedFieldName + "\")")
1✔
243
                    + " in " + targetField.getDeclaringClass().getSimpleName());
1✔
244
        }
245
    }
1✔
246
}
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