|
27 | 27 |
|
28 | 28 | import org.eclipse.microprofile.config.spi.Converter; |
29 | 29 | import org.jboss.logging.Logger; |
| 30 | +import org.junit.jupiter.api.Nested; |
30 | 31 | import org.mockito.Mock; |
31 | 32 |
|
32 | 33 | import io.quarkus.arc.InjectableInstance; |
@@ -101,6 +102,12 @@ QuarkusComponentTestConfiguration update(Class<?> testClass) { |
101 | 102 | List<AnnotationsTransformer> annotationsTransformers = new ArrayList<>(this.annotationsTransformers); |
102 | 103 | List<Converter<?>> configConverters = new ArrayList<>(this.configConverters); |
103 | 104 |
|
| 105 | + if (testClass.isAnnotationPresent(Nested.class)) { |
| 106 | + while (testClass.getEnclosingClass() != null) { |
| 107 | + testClass = testClass.getEnclosingClass(); |
| 108 | + } |
| 109 | + } |
| 110 | + |
104 | 111 | QuarkusComponentTest testAnnotation = testClass.getAnnotation(QuarkusComponentTest.class); |
105 | 112 | if (testAnnotation != null) { |
106 | 113 | Collections.addAll(componentClasses, testAnnotation.value()); |
@@ -130,67 +137,78 @@ QuarkusComponentTestConfiguration update(Class<?> testClass) { |
130 | 137 | } |
131 | 138 | Class<?> current = testClass; |
132 | 139 | while (current != null && current != Object.class) { |
133 | | - // All fields annotated with @Inject represent component classes |
134 | | - for (Field field : current.getDeclaredFields()) { |
135 | | - if (field.isAnnotationPresent(Inject.class)) { |
136 | | - if (Instance.class.isAssignableFrom(field.getType()) |
137 | | - || QuarkusComponentTestExtension.isListAllInjectionPoint(field.getGenericType(), |
138 | | - field.getAnnotations(), |
139 | | - field)) { |
140 | | - // Special handling for Instance<Foo> and @All List<Foo> |
141 | | - componentClasses |
142 | | - .add(getRawType( |
143 | | - QuarkusComponentTestExtension.getFirstActualTypeArgument(field.getGenericType()))); |
144 | | - } else if (!resolvesToBuiltinBean(field.getType())) { |
145 | | - componentClasses.add(field.getType()); |
146 | | - } |
| 140 | + collectComponents(current, addNestedClassesAsComponents, componentClasses); |
| 141 | + current = current.getSuperclass(); |
| 142 | + } |
| 143 | + |
| 144 | + // @TestConfigProperty annotations |
| 145 | + for (TestConfigProperty testConfigProperty : testClass.getAnnotationsByType(TestConfigProperty.class)) { |
| 146 | + configProperties.put(testConfigProperty.key(), testConfigProperty.value()); |
| 147 | + } |
| 148 | + |
| 149 | + return new QuarkusComponentTestConfiguration(Map.copyOf(configProperties), Set.copyOf(componentClasses), |
| 150 | + this.mockConfigurators, useDefaultConfigProperties, addNestedClassesAsComponents, configSourceOrdinal, |
| 151 | + List.copyOf(annotationsTransformers), List.copyOf(configConverters), configBuilderCustomizer); |
| 152 | + } |
| 153 | + |
| 154 | + private static void collectComponents(Class<?> testClass, boolean addNestedClassesAsComponents, |
| 155 | + List<Class<?>> componentClasses) { |
| 156 | + // All fields annotated with @Inject represent component classes |
| 157 | + for (Field field : testClass.getDeclaredFields()) { |
| 158 | + if (field.isAnnotationPresent(Inject.class)) { |
| 159 | + if (Instance.class.isAssignableFrom(field.getType()) |
| 160 | + || QuarkusComponentTestExtension.isListAllInjectionPoint(field.getGenericType(), |
| 161 | + field.getAnnotations(), |
| 162 | + field)) { |
| 163 | + // Special handling for Instance<Foo> and @All List<Foo> |
| 164 | + componentClasses |
| 165 | + .add(getRawType( |
| 166 | + QuarkusComponentTestExtension.getFirstActualTypeArgument(field.getGenericType()))); |
| 167 | + } else if (!resolvesToBuiltinBean(field.getType())) { |
| 168 | + componentClasses.add(field.getType()); |
147 | 169 | } |
148 | 170 | } |
149 | | - // All static nested classes declared on the test class are components |
150 | | - if (addNestedClassesAsComponents) { |
151 | | - for (Class<?> declaredClass : current.getDeclaredClasses()) { |
152 | | - if (Modifier.isStatic(declaredClass.getModifiers())) { |
153 | | - componentClasses.add(declaredClass); |
154 | | - } |
| 171 | + } |
| 172 | + // All static nested classes declared on the test class are components |
| 173 | + if (addNestedClassesAsComponents) { |
| 174 | + for (Class<?> declaredClass : testClass.getDeclaredClasses()) { |
| 175 | + if (Modifier.isStatic(declaredClass.getModifiers())) { |
| 176 | + componentClasses.add(declaredClass); |
155 | 177 | } |
156 | 178 | } |
157 | | - // All params of test methods but: |
158 | | - // - not covered by built-in extensions |
159 | | - // - not annotated with @InjectMock, @SkipInject, @org.mockito.Mock |
160 | | - for (Method method : current.getDeclaredMethods()) { |
161 | | - if (QuarkusComponentTestExtension.isTestMethod(method)) { |
162 | | - for (Parameter param : method.getParameters()) { |
163 | | - if (QuarkusComponentTestExtension.BUILTIN_PARAMETER.test(param) |
164 | | - || param.isAnnotationPresent(InjectMock.class) |
165 | | - || param.isAnnotationPresent(SkipInject.class) |
166 | | - || param.isAnnotationPresent(Mock.class)) { |
167 | | - continue; |
168 | | - } |
169 | | - if (Instance.class.isAssignableFrom(param.getType()) |
170 | | - || QuarkusComponentTestExtension.isListAllInjectionPoint(param.getParameterizedType(), |
171 | | - param.getAnnotations(), |
172 | | - param)) { |
173 | | - // Special handling for Instance<Foo> and @All List<Foo> |
174 | | - componentClasses.add(getRawType( |
175 | | - QuarkusComponentTestExtension.getFirstActualTypeArgument(param.getParameterizedType()))); |
176 | | - } else { |
177 | | - componentClasses.add(param.getType()); |
178 | | - } |
| 179 | + } |
| 180 | + // All params of test methods but: |
| 181 | + // - not covered by built-in extensions |
| 182 | + // - not annotated with @InjectMock, @SkipInject, @org.mockito.Mock |
| 183 | + for (Method method : testClass.getDeclaredMethods()) { |
| 184 | + if (QuarkusComponentTestExtension.isTestMethod(method)) { |
| 185 | + for (Parameter param : method.getParameters()) { |
| 186 | + if (QuarkusComponentTestExtension.BUILTIN_PARAMETER.test(param) |
| 187 | + || param.isAnnotationPresent(InjectMock.class) |
| 188 | + || param.isAnnotationPresent(SkipInject.class) |
| 189 | + || param.isAnnotationPresent(Mock.class)) { |
| 190 | + continue; |
| 191 | + } |
| 192 | + if (Instance.class.isAssignableFrom(param.getType()) |
| 193 | + || QuarkusComponentTestExtension.isListAllInjectionPoint(param.getParameterizedType(), |
| 194 | + param.getAnnotations(), |
| 195 | + param)) { |
| 196 | + // Special handling for Instance<Foo> and @All List<Foo> |
| 197 | + componentClasses.add(getRawType( |
| 198 | + QuarkusComponentTestExtension.getFirstActualTypeArgument(param.getParameterizedType()))); |
| 199 | + } else { |
| 200 | + componentClasses.add(param.getType()); |
179 | 201 | } |
180 | 202 | } |
181 | 203 | } |
182 | | - current = current.getSuperclass(); |
183 | 204 | } |
184 | 205 |
|
185 | | - List<TestConfigProperty> testConfigProperties = new ArrayList<>(); |
186 | | - Collections.addAll(testConfigProperties, testClass.getAnnotationsByType(TestConfigProperty.class)); |
187 | | - for (TestConfigProperty testConfigProperty : testConfigProperties) { |
188 | | - configProperties.put(testConfigProperty.key(), testConfigProperty.value()); |
| 206 | + // All @Nested inner classes |
| 207 | + for (Class<?> nested : testClass.getDeclaredClasses()) { |
| 208 | + if (nested.isAnnotationPresent(Nested.class) && !Modifier.isStatic(nested.getModifiers())) { |
| 209 | + collectComponents(nested, addNestedClassesAsComponents, componentClasses); |
| 210 | + } |
189 | 211 | } |
190 | | - |
191 | | - return new QuarkusComponentTestConfiguration(Map.copyOf(configProperties), Set.copyOf(componentClasses), |
192 | | - this.mockConfigurators, useDefaultConfigProperties, addNestedClassesAsComponents, configSourceOrdinal, |
193 | | - List.copyOf(annotationsTransformers), List.copyOf(configConverters), configBuilderCustomizer); |
194 | 212 | } |
195 | 213 |
|
196 | 214 | QuarkusComponentTestConfiguration update(Method testMethod) { |
|
0 commit comments