Register runtime hints for ApplicationContextInitializers in the TCF
This commit introduces automatic registration of runtime hints for ApplicationContextInitializers configured via the `initializers` attribute in @ContextConfiguration. See gh-29021
This commit is contained in:
@@ -112,6 +112,7 @@ public class TestContextAotGenerator {
|
|||||||
mergedConfigMappings.forEach((mergedConfig, testClasses) -> {
|
mergedConfigMappings.forEach((mergedConfig, testClasses) -> {
|
||||||
logger.debug(LogMessage.format("Generating AOT artifacts for test classes %s",
|
logger.debug(LogMessage.format("Generating AOT artifacts for test classes %s",
|
||||||
testClasses.stream().map(Class::getName).toList()));
|
testClasses.stream().map(Class::getName).toList()));
|
||||||
|
registerHintsForMergedConfig(mergedConfig);
|
||||||
try {
|
try {
|
||||||
// Use first test class discovered for a given unique MergedContextConfiguration.
|
// Use first test class discovered for a given unique MergedContextConfiguration.
|
||||||
Class<?> testClass = testClasses.get(0);
|
Class<?> testClass = testClasses.get(0);
|
||||||
@@ -174,8 +175,6 @@ public class TestContextAotGenerator {
|
|||||||
Consider annotating test class [%s] with @ContextConfiguration or \
|
Consider annotating test class [%s] with @ContextConfiguration or \
|
||||||
@ContextHierarchy.""".formatted(testClass.getName()));
|
@ContextHierarchy.""".formatted(testClass.getName()));
|
||||||
|
|
||||||
registerDeclaredConstructors(contextLoader.getClass());
|
|
||||||
|
|
||||||
if (contextLoader instanceof AotContextLoader aotContextLoader) {
|
if (contextLoader instanceof AotContextLoader aotContextLoader) {
|
||||||
try {
|
try {
|
||||||
ApplicationContext context = aotContextLoader.loadContextForAotProcessing(mergedConfig);
|
ApplicationContext context = aotContextLoader.loadContextForAotProcessing(mergedConfig);
|
||||||
@@ -227,6 +226,14 @@ public class TestContextAotGenerator {
|
|||||||
.registerType(TypeReference.of(className), MemberCategory.INVOKE_PUBLIC_METHODS);
|
.registerType(TypeReference.of(className), MemberCategory.INVOKE_PUBLIC_METHODS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void registerHintsForMergedConfig(MergedContextConfiguration mergedConfig) {
|
||||||
|
ContextLoader contextLoader = mergedConfig.getContextLoader();
|
||||||
|
if (contextLoader != null) {
|
||||||
|
registerDeclaredConstructors(contextLoader.getClass());
|
||||||
|
}
|
||||||
|
mergedConfig.getContextInitializerClasses().forEach(this::registerDeclaredConstructors);
|
||||||
|
}
|
||||||
|
|
||||||
private void registerDeclaredConstructors(Class<?> type) {
|
private void registerDeclaredConstructors(Class<?> type) {
|
||||||
ReflectionHints reflectionHints = this.runtimeHints.reflection();
|
ReflectionHints reflectionHints = this.runtimeHints.reflection();
|
||||||
reflectionHints.registerType(type, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
reflectionHints.registerType(type, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ class TestContextAotGeneratorTests extends AbstractAotTests {
|
|||||||
).forEach(type -> assertReflectionRegistered(runtimeHints, type, INVOKE_PUBLIC_CONSTRUCTORS));
|
).forEach(type -> assertReflectionRegistered(runtimeHints, type, INVOKE_PUBLIC_CONSTRUCTORS));
|
||||||
|
|
||||||
Set.of(
|
Set.of(
|
||||||
|
org.springframework.test.context.aot.samples.basic.BasicSpringTestNGTests.CustomInitializer.class,
|
||||||
org.springframework.test.context.support.AnnotationConfigContextLoader.class,
|
org.springframework.test.context.support.AnnotationConfigContextLoader.class,
|
||||||
org.springframework.test.context.support.DefaultTestContextBootstrapper.class,
|
org.springframework.test.context.support.DefaultTestContextBootstrapper.class,
|
||||||
org.springframework.test.context.support.DelegatingSmartContextLoader.class,
|
org.springframework.test.context.support.DelegatingSmartContextLoader.class,
|
||||||
|
|||||||
@@ -19,8 +19,11 @@ package org.springframework.test.context.aot.samples.basic;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextInitializer;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
import org.springframework.mock.env.MockPropertySource;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.TestPropertySource;
|
import org.springframework.test.context.aot.samples.basic.BasicSpringTestNGTests.CustomInitializer;
|
||||||
import org.springframework.test.context.aot.samples.common.MessageService;
|
import org.springframework.test.context.aot.samples.common.MessageService;
|
||||||
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
|
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
|
||||||
|
|
||||||
@@ -30,8 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
* @author Sam Brannen
|
* @author Sam Brannen
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
@ContextConfiguration(classes = BasicTestConfiguration.class)
|
@ContextConfiguration(classes = BasicTestConfiguration.class, initializers = CustomInitializer.class)
|
||||||
@TestPropertySource(properties = "test.engine = testng")
|
|
||||||
public class BasicSpringTestNGTests extends AbstractTestNGSpringContextTests {
|
public class BasicSpringTestNGTests extends AbstractTestNGSpringContextTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -51,4 +53,14 @@ public class BasicSpringTestNGTests extends AbstractTestNGSpringContextTests {
|
|||||||
.as("@TestPropertySource").isEqualTo("testng");
|
.as("@TestPropertySource").isEqualTo("testng");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class CustomInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(ConfigurableApplicationContext applicationContext) {
|
||||||
|
applicationContext.getEnvironment().getPropertySources()
|
||||||
|
.addFirst(new MockPropertySource().withProperty("test.engine", "testng"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user