At the request of the Spring Boot team, ApplicationContextFailureProcessor
implementations are now loaded via the spring.factories mechanism
instead of supporting a single processor registered via subclasses of
AbstractTestContextBootstrapper.
This makes the retrieval and handling of processors internal to
DefaultCacheAwareContextLoaderDelegate, while simultaneously supporting
multiple processors that can be registered by anyone (i.e., not
limited to projects that implement custom TestContextBootstrappers).
See gh-28826
Closes gh-29387
For a Spring Boot test, Logback logs at DEBUG level by default until
Spring Boot's logging infrastructure has a chance to take control, and
this can result in a considerable amount of INFO and DEBUG output.
It's not the number of lines that causes an issue. Rather, it's the
amount of information in each line that can become overwhelming,
especially when the MergedContextConfiguration is complex.
The main reason for lengthy DEBUG logging in a Spring Boot test is that
Spring Boot's ImportsContextCustomizer implements toString() which
results in logging of the fully qualified class names of all imported
configuration classes. In an example using @WebMvcTest, this resulted
in logging of 27 imported classes twice. However, the lists of
registered TestExecutionListener, ContextCustomizerFactory, and
ContextCustomizer implementations are also logged separately, and that
adds quite a bit of noise at DEBUG level.
This commit addresses these issues and simultaneously completely
revises logging within the Spring TestContext Framework (TCF).
- Numerous log statements are now logged at TRACE level instead of
DEBUG.
- Numerous log statements now have two modes. When logging at TRACE
level, fully qualified class names (or the results of invoking
toString() on related components) are included. When logging at DEBUG
level, simple names of classes are logged and the results of invoking
toString() on related components are omitted.
- toString() implementations in TCF components are now based on the
newly introduced SimpleValueStyler for ToStringCreator.
The combination of the above changes greatly reduces the amount of
DEBUG logging output in the TCF, but users can still access complete
details by switching to TRACE level logging.
Closes gh-29229
This commit exposes a "spring.aot.processing" system property when the
AOT engine is running. This can be used by code that need to react
differently when the application is being refreshed for AOT processing.
Closes gh-29340
This commit introduces an ApplicationContextFailureProcessor SPI in the
Spring TestContext Framework that allows third parties to process
failures that occur while a SmartContextLoader attempts to load an
ApplicationContext.
SmartContextLoader implementations must introduce a try-catch block
around the loading code and throw a ContextLoadException that wraps
the failed ApplicationContext and the cause of the failure.
Extensions of AbstractTestContextBootstrapper can configure an
ApplicationContextFailureProcessor by overriding the new protected
getApplicationContextFailureProcessor() method.
DefaultCacheAwareContextLoaderDelegate unwraps any ContextLoadException
and delegates to the configured ApplicationContextFailureProcessor for
processing.
Closes gh-28826
There's currently a considerable amount of overlap between the
implementations of AotProcessor and TestAotProcessor. In addition
AotProcessor is abstract and does not include a main() method; whereas,
TestAotProcessor is concrete and does include a main() method.
To address these issues, this commit:
- Introduces an AbstractAotProcessor base class that AotProcessor and
TestAotProcessor now both extend
- Moves common properties/functionality to AbstractAotProcessor
- Renames AotProcessor to ContextAotProcessor
- Makes TestAotProcessor abstract like ContextAotProcessor
- Removes the main() method from TestAotProcessor
Closes gh-29266
Prior to this commit, the AOT runtime support in the Spring TestContext
Framework (TCF) relied on the MergedContextConfiguration for a given
test class being the same as during the AOT processing phase. However,
this is not always the case. For example, Spring Boot "disables"
selected `ContextCustomizer` implementations during AOT runtime
execution.
See 0f325f98b5
To address that, this commit ensures that context caching works
properly during AOT runtime execution even if the
MergedContextConfiguration differs from what was produced during the
AOT processing phase. Specifically, this commit introduces
AotMergedContextConfiguration which is a MergedContextConfiguration
implementation based on an AOT-generated ApplicationContextInitializer.
AotMergedContextConfiguration wraps the MergedContextConfiguration
built during AOT runtime execution.
Interactions with the ContextCache are performed using the
AotMergedContextConfiguration; whereas, the ApplicationContext is
loaded using the original MergedContextConfiguration.
This commit also introduces a ContextCustomizerFactory that emulates
the ImportsContextCustomizerFactory in Spring Boot's testing support.
BasicSpringJupiterImportedConfigTests uses @Import to verify that the
context customizer works, and AotIntegrationTests has been updated to
execute BasicSpringJupiterImportedConfigTests after test classes whose
MergedContextConfiguration is identical during AOT runtime execution.
Without the fix in this commit, BasicSpringJupiterImportedConfigTests
would fail in AOT runtime mode since its ApplicationContext would be
pulled from the cache using an inappropriate cache key.
Closes gh-29289
Prior to this commit, the abstract base test classes for JUnit 4 and
TestNG registered explicit sets of TestExecutionListeners. This
configuration was useful in the early years of the Spring TestContext
Framework. However, since the introduction of support for automatic
registration of "default" listeners in Spring Framework 4.1, these
predefined sets of TestExecutionListeners have become a hindrance to
using Spring's testing support with default listeners from Spring
portfolio projects (such as Spring Boot and Spring Security) as well as
third-party or project-specific default listeners.
To address this issue, the four abstract base test classes for JUnit 4
and TestNG no longer declare listeners via @TestExecutionListeners and
instead now rely on registration of default listeners.
Closes gh-29149
Prior to this commit, ExchangeResult.assertWithDiagnostics() threw an
IllegalArgumentException for a custom HTTP status code since toString()
invoked getStatus() without a try-catch block.
This commit addresses this issue by introducing a formatStatus() method
that defensively formats the response status, initially trying to
format the HttpStatus and falling back to formatting the raw integer
status code.
Closes gh-29283
TestClassScanner was made public with the assumption that Spring Boot's
AOT testing support might need to work directly with that class; however,
it turns out that Spring Boot does not currently have such a need.
In light of that, this commit restores TestClassScanner's visibility to
package private.
Prior to this commit, the TestRuntimeHintsRegistrar API combined
processing of MergedContextConfiguration and test classes. However, it
appears that only spring-test internals have a need for registering
hints based on the MergedContextConfiguration. For example, Spring
Boot's AOT testing support has not had such a need, and it is assumed
that third parties likely will not have such a need.
In light of that, this commit simplifies the TestRuntimeHintsRegistrar
API so that it focuses on processing of a single test class.
In addition, this commit moves the hint registration code specific to
MergedContextConfiguration to an internal mechanism.
Closes gh-29264
This commit updates code generation to customize the instantiation of
a configuration class that requires a proxy. Rather than instantiating
the raw class, the proxy is used.
Closes gh-29107
New methods in DefaultResponseCreator for adding headers and cookies,
for specifying the character encoding when setting a string body on
a response, which is useful when working in environments that do not
automatically assume UTF-8, such as integrating with legacy
applications from a new Spring one.
New methods in MockRestResponseCreators support extra commonly used
HTTP status codes, including some that occur when working in AWS,
CloudFlare, or when using gateways such as Kong, where resilient
applications should be able to respond to ratelimits, gateway errors,
and gateway timeouts that may occur if a remote service is down.
Added test cases for any changes made.
See gh-27280
This commit updates ClassNameGenerator so that it uses a ClassName for
its default target. This makes sure that a target that has been
generated can be used.
See gh-29027
This commit improves `TestCompiler` with a `with` function that allows
to customize a test compiler instance. Rather than `TestCompiler`
knowing about `TestGenerationContext`, the latter implements the
function so that it can be passed as is.
See gh-29175