1717package org .springframework .test .context .aot ;
1818
1919import java .lang .annotation .Annotation ;
20+ import java .lang .reflect .Proxy ;
2021import java .util .ArrayList ;
2122import java .util .List ;
2223import java .util .Set ;
2324import java .util .stream .Stream ;
2425
2526import javax .sql .DataSource ;
2627
28+ import org .assertj .core .util .Arrays ;
29+ import org .easymock .EasyMockSupport ;
2730import org .junit .jupiter .api .Test ;
31+ import org .mockito .Mockito ;
2832
2933import org .springframework .aot .AotDetector ;
3034import org .springframework .aot .generate .DefaultGenerationContext ;
3741import org .springframework .context .ApplicationContext ;
3842import org .springframework .context .ApplicationContextInitializer ;
3943import org .springframework .context .ConfigurableApplicationContext ;
44+ import org .springframework .context .aot .AbstractAotProcessor ;
4045import org .springframework .core .test .tools .CompileWithForkedClassLoader ;
4146import org .springframework .core .test .tools .TestCompiler ;
4247import org .springframework .javapoet .ClassName ;
4752import org .springframework .test .context .aot .samples .basic .BasicSpringJupiterTests ;
4853import org .springframework .test .context .aot .samples .basic .BasicSpringTestNGTests ;
4954import org .springframework .test .context .aot .samples .basic .BasicSpringVintageTests ;
55+ import org .springframework .test .context .aot .samples .bean .override .EasyMockBeanJupiterTests ;
56+ import org .springframework .test .context .aot .samples .bean .override .MockitoBeanJupiterTests ;
57+ import org .springframework .test .context .aot .samples .common .GreetingService ;
5058import org .springframework .test .context .aot .samples .common .MessageService ;
5159import org .springframework .test .context .aot .samples .jdbc .SqlScriptsSpringJupiterTests ;
5260import org .springframework .test .context .aot .samples .web .WebSpringJupiterTests ;
6775import static org .springframework .aot .hint .MemberCategory .INVOKE_DECLARED_METHODS ;
6876import static org .springframework .aot .hint .MemberCategory .INVOKE_PUBLIC_CONSTRUCTORS ;
6977import static org .springframework .aot .hint .MemberCategory .INVOKE_PUBLIC_METHODS ;
78+ import static org .springframework .aot .hint .predicate .RuntimeHintsPredicates .proxies ;
7079import static org .springframework .aot .hint .predicate .RuntimeHintsPredicates .reflection ;
7180import static org .springframework .aot .hint .predicate .RuntimeHintsPredicates .resource ;
7281import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .get ;
@@ -97,14 +106,25 @@ void endToEndTests() {
97106 BasicSpringJupiterTests .NestedTests .class ,
98107 BasicSpringTestNGTests .class ,
99108 BasicSpringVintageTests .class ,
109+ EasyMockBeanJupiterTests .class ,
110+ MockitoBeanJupiterTests .class ,
100111 SqlScriptsSpringJupiterTests .class ,
101112 XmlSpringJupiterTests .class ,
102113 WebSpringJupiterTests .class );
103114
104115 InMemoryGeneratedFiles generatedFiles = new InMemoryGeneratedFiles ();
105116 TestContextAotGenerator generator = new TestContextAotGenerator (generatedFiles );
106117
107- generator .processAheadOfTime (testClasses .stream ().sorted (comparing (Class ::getName )));
118+ try {
119+ // Emulate AbstractAotProcessor.process().
120+ System .setProperty (AbstractAotProcessor .AOT_PROCESSING , "true" );
121+
122+ generator .processAheadOfTime (testClasses .stream ().sorted (comparing (Class ::getName )));
123+ }
124+ finally {
125+ // Emulate AbstractAotProcessor.process().
126+ System .clearProperty (AbstractAotProcessor .AOT_PROCESSING );
127+ }
108128
109129 assertRuntimeHints (generator .getRuntimeHints ());
110130
@@ -142,6 +162,12 @@ void endToEndTests() {
142162 else if (testClass .getPackageName ().contains ("jdbc" )) {
143163 assertContextForJdbcTests (context );
144164 }
165+ else if (testClass .equals (EasyMockBeanJupiterTests .class )) {
166+ assertContextForEasyMockBeanOverrideTests (context );
167+ }
168+ else if (testClass .equals (MockitoBeanJupiterTests .class )) {
169+ assertContextForMockitoBeanOverrideTests (context );
170+ }
145171 else {
146172 assertContextForBasicTests (context );
147173 }
@@ -243,6 +269,15 @@ private static void assertRuntimeHints(RuntimeHints runtimeHints) {
243269 .accepts (runtimeHints );
244270 assertThat (resource ().forResource ("org/springframework/test/context/aot/samples/jdbc/SqlScriptsSpringJupiterTests.test.sql" ))
245271 .accepts (runtimeHints );
272+
273+ // @BeanOverride(value = ...)
274+ assertReflectionRegistered (runtimeHints , "org.springframework.test.context.bean.override.mockito.MockitoBeanOverrideProcessor" ,
275+ INVOKE_DECLARED_CONSTRUCTORS );
276+
277+ // GenericApplicationContext.preDetermineBeanTypes() should have registered proxy
278+ // hints for the EasyMock interface-based mocks.
279+ assertProxyRegistered (runtimeHints , GreetingService .class );
280+ assertProxyRegistered (runtimeHints , MessageService .class );
246281 }
247282
248283 private static void assertReflectionRegistered (RuntimeHints runtimeHints , String type ) {
@@ -267,6 +302,13 @@ private static void assertAnnotationRegistered(RuntimeHints runtimeHints, Class<
267302 assertReflectionRegistered (runtimeHints , annotationType , INVOKE_DECLARED_METHODS );
268303 }
269304
305+ private static void assertProxyRegistered (RuntimeHints runtimeHints , Class <?>... interfaces ) {
306+ assertThat (proxies ().forInterfaces (interfaces ))
307+ .as ("Proxy hint for %s" , Arrays .asList (interfaces ))
308+ .accepts (runtimeHints );
309+ }
310+
311+
270312
271313 @ Test
272314 void processAheadOfTimeWithBasicTests () {
@@ -297,6 +339,24 @@ private void assertContextForJdbcTests(ApplicationContext context) {
297339 assertThat (context .getBean (DataSource .class )).as ("DataSource" ).isNotNull ();
298340 }
299341
342+ private void assertContextForEasyMockBeanOverrideTests (ApplicationContext context ) {
343+ GreetingService greetingService = context .getBean (GreetingService .class );
344+ MessageService messageService = context .getBean (MessageService .class );
345+
346+ assertThat (EasyMockSupport .isAMock (greetingService )).as ("EasyMock mock" ).isTrue ();
347+ assertThat (EasyMockSupport .isAMock (messageService )).as ("EasyMock mock" ).isTrue ();
348+ assertThat (Proxy .isProxyClass (greetingService .getClass ())).as ("JDK proxy" ).isTrue ();
349+ assertThat (Proxy .isProxyClass (messageService .getClass ())).as ("JDK proxy" ).isTrue ();
350+ }
351+
352+ private void assertContextForMockitoBeanOverrideTests (ApplicationContext context ) {
353+ GreetingService greetingService = context .getBean (GreetingService .class );
354+ MessageService messageService = context .getBean (MessageService .class );
355+
356+ assertThat (Mockito .mockingDetails (greetingService ).isMock ()).as ("Mockito mock" ).isTrue ();
357+ assertThat (Mockito .mockingDetails (messageService ).isMock ()).as ("Mockito mock" ).isTrue ();
358+ }
359+
300360 private void assertContextForWebTests (WebApplicationContext wac ) throws Exception {
301361 assertThat (wac .getEnvironment ().getProperty ("test.engine" )).as ("Environment" ).isNotNull ();
302362
@@ -364,10 +424,19 @@ private List<Mapping> processAheadOfTime(TestContextAotGenerator generator, Set<
364424 testClasses .forEach (testClass -> {
365425 DefaultGenerationContext generationContext = generator .createGenerationContext (testClass );
366426 MergedContextConfiguration mergedConfig = buildMergedContextConfiguration (testClass );
367- ClassName className = generator .processAheadOfTime (mergedConfig , generationContext );
368- assertThat (className ).isNotNull ();
369- mappings .add (new Mapping (mergedConfig , className ));
370- generationContext .writeGeneratedContent ();
427+ try {
428+ // Emulate AbstractAotProcessor.process().
429+ System .setProperty (AbstractAotProcessor .AOT_PROCESSING , "true" );
430+
431+ ClassName className = generator .processAheadOfTime (mergedConfig , generationContext );
432+ assertThat (className ).isNotNull ();
433+ mappings .add (new Mapping (mergedConfig , className ));
434+ generationContext .writeGeneratedContent ();
435+ }
436+ finally {
437+ // Emulate AbstractAotProcessor.process().
438+ System .clearProperty (AbstractAotProcessor .AOT_PROCESSING );
439+ }
371440 });
372441 return mappings ;
373442 }
@@ -422,29 +491,43 @@ record Mapping(MergedContextConfiguration mergedConfig, ClassName className) {
422491 "org/springframework/test/context/aot/samples/basic/BasicSpringVintageTests__TestContext004_BeanFactoryRegistrations.java" ,
423492 "org/springframework/test/context/aot/samples/basic/BasicTestConfiguration__TestContext004_BeanDefinitions.java" ,
424493 "org/springframework/test/context/support/DynamicPropertyRegistrarBeanInitializer__TestContext004_BeanDefinitions.java" ,
425- // SqlScriptsSpringJupiterTests
494+ // EasyMockBeanJupiterTests
426495 "org/springframework/context/event/DefaultEventListenerFactory__TestContext005_BeanDefinitions.java" ,
427496 "org/springframework/context/event/EventListenerMethodProcessor__TestContext005_BeanDefinitions.java" ,
428- "org/springframework/test/context/aot/samples/jdbc/SqlScriptsSpringJupiterTests__TestContext005_ApplicationContextInitializer .java" ,
429- "org/springframework/test/context/aot/samples/jdbc/SqlScriptsSpringJupiterTests__TestContext005_BeanFactoryRegistrations .java" ,
430- "org/springframework/test/context/jdbc/EmptyDatabaseConfig__TestContext005_BeanDefinitions .java" ,
497+ "org/springframework/test/context/aot/samples/bean/override/EasyMockBeanJupiterTests__TestContext005_ApplicationContextInitializer .java" ,
498+ "org/springframework/test/context/aot/samples/bean/override/EasyMockBeanJupiterTests__TestContext005_BeanDefinitions .java" ,
499+ "org/springframework/test/context/aot/samples/bean/override/EasyMockBeanJupiterTests__TestContext005_BeanFactoryRegistrations .java" ,
431500 "org/springframework/test/context/support/DynamicPropertyRegistrarBeanInitializer__TestContext005_BeanDefinitions.java" ,
432- // WebSpringJupiterTests
501+ // MockitoBeanJupiterTests
433502 "org/springframework/context/event/DefaultEventListenerFactory__TestContext006_BeanDefinitions.java" ,
434503 "org/springframework/context/event/EventListenerMethodProcessor__TestContext006_BeanDefinitions.java" ,
435- "org/springframework/test/context/aot/samples/web/WebSpringJupiterTests__TestContext006_ApplicationContextInitializer.java" ,
436- "org/springframework/test/context/aot/samples/web/WebSpringJupiterTests__TestContext006_BeanFactoryRegistrations.java" ,
437- "org/springframework/test/context/aot/samples/web/WebTestConfiguration__TestContext006_BeanDefinitions.java" ,
438- "org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration__TestContext006_Autowiring.java" ,
439- "org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration__TestContext006_BeanDefinitions.java" ,
504+ "org/springframework/test/context/aot/samples/bean/override/MockitoBeanJupiterTests__TestContext006_ApplicationContextInitializer.java" ,
505+ "org/springframework/test/context/aot/samples/bean/override/MockitoBeanJupiterTests__TestContext006_BeanDefinitions.java" ,
506+ "org/springframework/test/context/aot/samples/bean/override/MockitoBeanJupiterTests__TestContext006_BeanFactoryRegistrations.java" ,
440507 "org/springframework/test/context/support/DynamicPropertyRegistrarBeanInitializer__TestContext006_BeanDefinitions.java" ,
441- // XmlSpringJupiterTests
508+ // SqlScriptsSpringJupiterTests
442509 "org/springframework/context/event/DefaultEventListenerFactory__TestContext007_BeanDefinitions.java" ,
443510 "org/springframework/context/event/EventListenerMethodProcessor__TestContext007_BeanDefinitions.java" ,
444- "org/springframework/test/context/aot/samples/common/DefaultMessageService__TestContext007_BeanDefinitions .java" ,
445- "org/springframework/test/context/aot/samples/xml/XmlSpringJupiterTests__TestContext007_ApplicationContextInitializer .java" ,
446- "org/springframework/test/context/aot/samples/xml/XmlSpringJupiterTests__TestContext007_BeanFactoryRegistrations .java" ,
511+ "org/springframework/test/context/aot/samples/jdbc/SqlScriptsSpringJupiterTests__TestContext007_ApplicationContextInitializer .java" ,
512+ "org/springframework/test/context/aot/samples/jdbc/SqlScriptsSpringJupiterTests__TestContext007_BeanFactoryRegistrations .java" ,
513+ "org/springframework/test/context/jdbc/EmptyDatabaseConfig__TestContext007_BeanDefinitions .java" ,
447514 "org/springframework/test/context/support/DynamicPropertyRegistrarBeanInitializer__TestContext007_BeanDefinitions.java" ,
515+ // WebSpringJupiterTests
516+ "org/springframework/context/event/DefaultEventListenerFactory__TestContext008_BeanDefinitions.java" ,
517+ "org/springframework/context/event/EventListenerMethodProcessor__TestContext008_BeanDefinitions.java" ,
518+ "org/springframework/test/context/aot/samples/web/WebSpringJupiterTests__TestContext008_ApplicationContextInitializer.java" ,
519+ "org/springframework/test/context/aot/samples/web/WebSpringJupiterTests__TestContext008_BeanFactoryRegistrations.java" ,
520+ "org/springframework/test/context/aot/samples/web/WebTestConfiguration__TestContext008_BeanDefinitions.java" ,
521+ "org/springframework/test/context/support/DynamicPropertyRegistrarBeanInitializer__TestContext008_BeanDefinitions.java" ,
522+ "org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration__TestContext008_Autowiring.java" ,
523+ "org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration__TestContext008_BeanDefinitions.java" ,
524+ // XmlSpringJupiterTests
525+ "org/springframework/context/event/DefaultEventListenerFactory__TestContext009_BeanDefinitions.java" ,
526+ "org/springframework/context/event/EventListenerMethodProcessor__TestContext009_BeanDefinitions.java" ,
527+ "org/springframework/test/context/aot/samples/common/DefaultMessageService__TestContext009_BeanDefinitions.java" ,
528+ "org/springframework/test/context/aot/samples/xml/XmlSpringJupiterTests__TestContext009_ApplicationContextInitializer.java" ,
529+ "org/springframework/test/context/aot/samples/xml/XmlSpringJupiterTests__TestContext009_BeanFactoryRegistrations.java" ,
530+ "org/springframework/test/context/support/DynamicPropertyRegistrarBeanInitializer__TestContext009_BeanDefinitions.java" ,
448531 };
449532
450533}
0 commit comments