16
16
17
17
package org .springframework .test .context .aot ;
18
18
19
+ import java .lang .annotation .Annotation ;
19
20
import java .util .ArrayList ;
20
21
import java .util .List ;
21
22
import java .util .Set ;
23
+ import java .util .function .Consumer ;
22
24
23
25
import org .junit .jupiter .api .Test ;
24
26
25
27
import org .springframework .aot .generate .DefaultGenerationContext ;
26
28
import org .springframework .aot .generate .GeneratedFiles .Kind ;
27
29
import org .springframework .aot .generate .InMemoryGeneratedFiles ;
30
+ import org .springframework .aot .hint .JdkProxyHint ;
28
31
import org .springframework .aot .hint .MemberCategory ;
29
- import org .springframework .aot .hint .ReflectionHints ;
32
+ import org .springframework .aot .hint .RuntimeHints ;
30
33
import org .springframework .aot .hint .TypeReference ;
31
34
import org .springframework .aot .test .generator .compile .CompileWithTargetClassAccess ;
32
35
import org .springframework .aot .test .generator .compile .TestCompiler ;
33
36
import org .springframework .context .ApplicationContext ;
34
37
import org .springframework .context .ApplicationContextInitializer ;
35
38
import org .springframework .context .ConfigurableApplicationContext ;
39
+ import org .springframework .core .annotation .SynthesizedAnnotation ;
36
40
import org .springframework .javapoet .ClassName ;
37
41
import org .springframework .test .context .MergedContextConfiguration ;
38
42
import org .springframework .test .context .aot .samples .basic .BasicSpringJupiterSharedConfigTests ;
52
56
53
57
import static java .util .Comparator .comparing ;
54
58
import static org .assertj .core .api .Assertions .assertThat ;
59
+ import static org .springframework .aot .hint .MemberCategory .INVOKE_DECLARED_CONSTRUCTORS ;
60
+ import static org .springframework .aot .hint .MemberCategory .INVOKE_DECLARED_METHODS ;
61
+ import static org .springframework .aot .hint .MemberCategory .INVOKE_PUBLIC_CONSTRUCTORS ;
62
+ import static org .springframework .aot .hint .MemberCategory .INVOKE_PUBLIC_METHODS ;
63
+ import static org .springframework .aot .hint .predicate .RuntimeHintsPredicates .reflection ;
55
64
import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .get ;
56
65
import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .content ;
57
66
import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .status ;
@@ -83,10 +92,7 @@ void processAheadOfTimeAndGenerateAotTestMappings() {
83
92
84
93
generator .processAheadOfTime (testClasses .stream ().sorted (comparing (Class ::getName )));
85
94
86
- ReflectionHints reflectionHints = generator .getRuntimeHints ().reflection ();
87
- assertThat (reflectionHints .getTypeHint (TypeReference .of (AotTestMappings .GENERATED_MAPPINGS_CLASS_NAME )))
88
- .satisfies (typeHint ->
89
- assertThat (typeHint .getMemberCategories ()).containsExactly (MemberCategory .INVOKE_PUBLIC_METHODS ));
95
+ assertRuntimeHints (generator .getRuntimeHints ());
90
96
91
97
List <String > sourceFiles = generatedFiles .getGeneratedFiles (Kind .SOURCE ).keySet ().stream ().toList ();
92
98
assertThat (sourceFiles ).containsExactlyInAnyOrder (expectedSourceFilesForBasicSpringTests );
@@ -105,6 +111,101 @@ void processAheadOfTimeAndGenerateAotTestMappings() {
105
111
}));
106
112
}
107
113
114
+ private static void assertRuntimeHints (RuntimeHints runtimeHints ) {
115
+ assertReflectionRegistered (runtimeHints , AotTestMappings .GENERATED_MAPPINGS_CLASS_NAME , INVOKE_PUBLIC_METHODS );
116
+
117
+ Set .of (
118
+ org .springframework .test .context .cache .DefaultCacheAwareContextLoaderDelegate .class ,
119
+ org .springframework .test .context .support .DefaultBootstrapContext .class ,
120
+ org .springframework .test .context .support .DelegatingSmartContextLoader .class ,
121
+ org .springframework .test .context .web .WebDelegatingSmartContextLoader .class
122
+ ).forEach (type -> assertReflectionRegistered (runtimeHints , type , INVOKE_PUBLIC_CONSTRUCTORS ));
123
+
124
+ Set .of (
125
+ org .springframework .test .context .support .DefaultTestContextBootstrapper .class ,
126
+ org .springframework .test .context .web .WebTestContextBootstrapper .class ,
127
+ org .springframework .test .context .support .GenericGroovyXmlContextLoader .class ,
128
+ org .springframework .test .context .web .GenericGroovyXmlWebContextLoader .class
129
+ ).forEach (type -> assertReflectionRegistered (runtimeHints , type , INVOKE_DECLARED_CONSTRUCTORS ));
130
+
131
+ Set .of (
132
+ // Legacy and JUnit 4
133
+ org .springframework .test .annotation .Commit .class ,
134
+ org .springframework .test .annotation .DirtiesContext .class ,
135
+ org .springframework .test .annotation .IfProfileValue .class ,
136
+ org .springframework .test .annotation .ProfileValueSourceConfiguration .class ,
137
+ org .springframework .test .annotation .Repeat .class ,
138
+ org .springframework .test .annotation .Rollback .class ,
139
+ org .springframework .test .annotation .Timed .class ,
140
+
141
+ // Core TestContext framework
142
+ org .springframework .test .context .ActiveProfiles .class ,
143
+ org .springframework .test .context .BootstrapWith .class ,
144
+ org .springframework .test .context .ContextConfiguration .class ,
145
+ org .springframework .test .context .ContextHierarchy .class ,
146
+ org .springframework .test .context .DynamicPropertySource .class ,
147
+ org .springframework .test .context .NestedTestConfiguration .class ,
148
+ org .springframework .test .context .TestConstructor .class ,
149
+ org .springframework .test .context .TestExecutionListeners .class ,
150
+ org .springframework .test .context .TestPropertySource .class ,
151
+ org .springframework .test .context .TestPropertySources .class ,
152
+
153
+ // Application Events
154
+ org .springframework .test .context .event .RecordApplicationEvents .class ,
155
+
156
+ // JUnit Jupiter
157
+ org .springframework .test .context .junit .jupiter .EnabledIf .class ,
158
+ org .springframework .test .context .junit .jupiter .DisabledIf .class ,
159
+ org .springframework .test .context .junit .jupiter .SpringJUnitConfig .class ,
160
+ org .springframework .test .context .junit .jupiter .web .SpringJUnitWebConfig .class ,
161
+
162
+ // Web
163
+ org .springframework .test .context .web .WebAppConfiguration .class
164
+ ).forEach (type -> assertAnnotationRegistered (runtimeHints , type ));
165
+
166
+ // TestExecutionListener
167
+ Set .of (
168
+ org .springframework .test .context .event .ApplicationEventsTestExecutionListener .class ,
169
+ org .springframework .test .context .event .EventPublishingTestExecutionListener .class ,
170
+ org .springframework .test .context .jdbc .SqlScriptsTestExecutionListener .class ,
171
+ org .springframework .test .context .support .DependencyInjectionTestExecutionListener .class ,
172
+ org .springframework .test .context .support .DirtiesContextBeforeModesTestExecutionListener .class ,
173
+ org .springframework .test .context .support .DirtiesContextTestExecutionListener .class ,
174
+ org .springframework .test .context .transaction .TransactionalTestExecutionListener .class ,
175
+ org .springframework .test .context .web .ServletTestExecutionListener .class
176
+ ).forEach (type -> assertReflectionRegistered (runtimeHints , type , INVOKE_DECLARED_CONSTRUCTORS ));
177
+
178
+ // ContextCustomizerFactory
179
+ Set .of (
180
+ "org.springframework.test.context.support.DynamicPropertiesContextCustomizerFactory" ,
181
+ "org.springframework.test.context.web.socket.MockServerContainerContextCustomizerFactory"
182
+ ).forEach (type -> assertReflectionRegistered (runtimeHints , type , INVOKE_DECLARED_CONSTRUCTORS ));
183
+ }
184
+
185
+ private static void assertReflectionRegistered (RuntimeHints runtimeHints , String type , MemberCategory memberCategory ) {
186
+ assertThat (reflection ().onType (TypeReference .of (type )).withMemberCategory (memberCategory ))
187
+ .as ("Reflection hint for %s with category %s" , type , memberCategory )
188
+ .accepts (runtimeHints );
189
+ }
190
+
191
+ private static void assertReflectionRegistered (RuntimeHints runtimeHints , Class <?> type , MemberCategory memberCategory ) {
192
+ assertThat (reflection ().onType (type ).withMemberCategory (memberCategory ))
193
+ .as ("Reflection hint for %s with category %s" , type .getSimpleName (), memberCategory )
194
+ .accepts (runtimeHints );
195
+ }
196
+
197
+ private static void assertAnnotationRegistered (RuntimeHints runtimeHints , Class <? extends Annotation > annotationType ) {
198
+ assertReflectionRegistered (runtimeHints , annotationType , INVOKE_DECLARED_METHODS );
199
+ assertThat (runtimeHints .proxies ().jdkProxies ())
200
+ .as ("Proxy hint for annotation @%s" , annotationType .getSimpleName ())
201
+ .anySatisfy (annotationProxy (annotationType ));
202
+ }
203
+
204
+ private static Consumer <JdkProxyHint > annotationProxy (Class <? extends Annotation > type ) {
205
+ return jdkProxyHint -> assertThat (jdkProxyHint .getProxiedInterfaces ())
206
+ .containsExactly (TypeReference .of (type ), TypeReference .of (SynthesizedAnnotation .class ));
207
+ }
208
+
108
209
@ Test
109
210
void processAheadOfTimeWithBasicTests () {
110
211
// We cannot parameterize with the test classes, since @CompileWithTargetClassAccess
0 commit comments