This commit refactors the XML configuration used by the tests in the
Spr8849Tests test suite so that a unique database name is always
generated (via the new 'database-name' attribute that was introduced in
SPR-12835) while reusing the same bean name (i.e., 'dataSource').
This is a much more robust alternative to the previous work-around
since the name of the DataSource does not randomly change across
application contexts, thus allowing proper autowiring by name and bean
referencing within XML configuration.
Issue: SPR-8849
This commit simplifies the implementations of loadBeanDefinitions() in
GenericGroovyXmlContextLoader and GenericGroovyXmlWebContextLoader.
Due to the recent bug fix for GroovyBeanDefinitionReader regarding full
support for XML config files, these Groovy context loaders can now
simply use a GroovyBeanDefinitionReader instead of a
GroovyBeanDefinitionReader plus an XmlBeanDefinitionReader.
Issue: SPR-12769
Prior to this commit, it was impossible to use all features of XML
configuration (e.g., the <qualifier> tag) in web-based integration
tests (loaded using @WebAppConfiguration, @ContextConfiguration, etc.)
if the Groovy library was on the classpath. The reason is that the
GroovyBeanDefinitionReader used internally by
GenericGroovyXmlWebContextLoader disables XML validation for its
internal XmlBeanDefinitionReader, and this prevents some XML
configuration features from working properly. For example, the default
value for the 'type' attribute (defined in the spring-beans XSD) of the
<qualifier> tag gets ignored, resulting in an exception when the
application context is loaded.
This commit addresses this issue by refactoring the implementation of
loadBeanDefinitions() in GenericGroovyXmlWebContextLoader to use an
XmlBeanDefinitionReader or GroovyBeanDefinitionReader depending on the
file extension of the resource location from which bean definitions
should be loaded. This aligns the functionality of
GenericGroovyXmlWebContextLoader with the existing functionality of
GenericGroovyXmlContextLoader.
Issue: SPR-12768
- Added assertions for pre-conditions on method arguments for all
public utility methods.
- Introduced additional tests in TestPropertySourceUtilsTests to verify
the new pre-conditions.
- Introduced INLINED_PROPERTIES_PROPERTY_SOURCE_NAME constant for the
name of the MapPropertySource created from inlined properties; the
name therefore no longer contains the inlined properties, but the
original values of the inlined properties can now be logged at debug
level.
- Simplified tests in InlinedPropertiesTestPropertySourceTests.
Issue: SPR-12721
Spring Framework 4.1 introduced support for @TestPropertySource;
however, the utilities used to parse inlined properties and add test
property sources to the environment are currently private which
prevents reuse by third-party frameworks like Spring Boot.
This commit addresses this issue by making such utilities public.
- TestPropertySourceUtils is now a public class.
- Various utility methods in TestPropertySourceUtils have been made
public.
- addResourcePropertySourcesToEnvironment() has been renamed to
addPropertiesFilesToEnvironment().
- extractEnvironmentProperties() has been renamed to
convertInlinedPropertiesToMap().
- All public methods in TestPropertySourceUtils are now fully
documented.
Issue: SPR-12721
The initial implementation for adding inlined properties configured via
@TestPropertySource to the context's environment did not preserve the
order in which the properties were physically declared. This makes
@TestPropertySource a poor testing facility for mimicking the
production environment's configuration if the property source mechanism
used in production preserves ordering of property names -- which is the
case for YAML-based property sources used in Spring Boot, Spring Yarn,
etc.
This commit addresses this issue by ensuring that the ordering of
inlined properties declared via @TestPropertySource is preserved.
Specifically, the original functionality has been refactored. extracted
from AbstractContextLoader, and moved to TestPropertySourceUtils where
it may later be made public for general purpose use in other frameworks.
Issue: SPR-12710
This commit introduces further regression tests to ensure proper parsing
of inlined properties configured via @TestPropertySource. Specifically,
these additional tests ensure that we do not introduce a bug like the
one raised in Spring Boot issue #1110 [0].
[0] https://github.com/spring-projects/spring-boot/issues/1110
Issue: SPR-12710
Add support for annotation-based event listeners. Enabled automatically
when using Java configuration or can be enabled explicitly via the
regular <context:annotation-driven/> XML element. Detect methods of
managed beans annotated with @EventListener, either directly or through
a meta-annotation.
Annotated methods must define the event type they listen to as a single
parameter argument. Events are automatically filtered out according to
the method signature. When additional runtime filtering is required, one
can specify the `condition` attribute of the annotation that defines a
SpEL expression that should match to actually invoke the method for a
particular event. The root context exposes the actual `event`
(`#root.event`) and method arguments (`#root.args`). Individual method
arguments are also exposed via either the `a` or `p` alias (`#a0` refers
to the first method argument). Finally, methods arguments are exposed via
their names if that information can be discovered.
Events can be either an ApplicationEvent or any arbitrary payload. Such
payload is wrapped automatically in a PayloadApplicationEvent and managed
explicitly internally. As a result, users can now publish and listen
for arbitrary objects.
If an annotated method has a return value, an non null result is actually
published as a new event, something like:
@EventListener
public FooEvent handle(BarEvent event) { ... }
Events can be handled in an aynchronous manner by adding `@Async` to the
event method declaration and enabling such infrastructure. Events can
also be ordered by adding an `@Order` annotation to the event method.
Issue: SPR-11622
Spring Framework 4.0 introduced support for using test-related
annotations as meta-annotations in the Spring TestContext Framework
(TCF) in order to create custom composed annotations within a test
suite; however, the detection of default @Configuration classes in test
classes was not updated to search for @Configuration declared as a
meta-annotation. Specifically, AnnotationConfigContextLoaderUtils
invokes Class.isAnnotated() which only searches for annotations
declared directly on the class in question.
This commit addresses this issue by refactoring the
isDefaultConfigurationClassCandidate() method in
AnnotationConfigContextLoaderUtils so that it uses
AnnotationUtils.findAnnotation() instead of Class.isAnnotated() for
detecting the presence of the @Configuration annotation, either
directly or as a meta-annotation.
Issue: SPR-12659
Various parts of the reference manual as well as the Javadoc for
AnnotationConfigContextLoaderUtils improperly refer to "static inner
classes" even though this terminology does not exist in Java. The Java
Language Specification explicitly refers to such classes as "static
nested classes." An "inner class" must be non-static by definition.
In order to allow DefaultActiveProfilesResolver to be reused (e.g., via
extension or delegation), the check which asserts that the 'resolver'
attribute of @ActiveProfiles is not set to a customer resolver class
has been removed.
Issue: SPR-12611
JUnit 4.9 introduced a regression in BlockJUnit4ClassRunner.runChild()
such that exceptions thrown from methodBlock() cause the current test
execution to abort immediately. As a result, the failing test method is
unrooted, and subsequent test methods are never invoked. Furthermore,
RunListeners registered with JUnit are not properly notified.
In conjunction with SPR-11908, SpringJUnit4ClassRunner was updated to
use the aforementioned changes to BlockJUnit4ClassRunner.runChild().
Consequently, SpringJUnit4ClassRunner now suffers from the same
regression.
This commit addresses this issue by ensuring that any exceptions thrown
during the invocation of methodBlock() are properly wrapped in a JUnit
Fail Statement.
Issue: SPR-12613
Prior to this commit, finding out how many application contexts had
been loaded within a test suite required the use of reflection and a
bit of hacking.
This commit addresses this issue by logging ContextCache statistics
whenever an application context is loaded by the Spring TestContext
Framework (TCF).
The log output can be enabled by setting the
"org.springframework.test.context.cache" logging category to DEBUG.
Issue: SPR-12409
Prior to this commit, the getter methods in MockServletContext threw an
UnsupportedOperationException when trying to retrieve Servlet and
Filter registrations.
This commit improves the behavior of these methods by returning null
when a single registration is requested and an empty map when all
registrations are requested. This is now in line with the Javadoc for
ServletContext. Note, however, that the corresponding setter methods
still throw UnsupportedOperationExceptions which is suitable behavior
for a mock.
Issue: SPR-12290
Prior to this commit, AssertThrows in the spring-test module only
supported Exception; however, there are legitimate test cases where the
subject under test (SUT) may potentially throw a subclass of Throwable.
This commit refactors AssertThrows so that it supports exceptions of
type Throwable instead of the limiting support for Exception.
Furthermore, AssertThrows has been refactored to use generics (e.g.,
Class<? extends Throwable> instead of merely Class).
Issue: SPR-6362