Prior to this commit, if a custom TestExecutionListener was registered
via @TestExecutionListeners the defaults would not be registered. Thus,
if a user wanted to declare a custom listener and use the default
listeners, the user was forced to manually declare all default
listeners in addition to any custom listeners. This unfortunately
required that the user know exactly which listeners were registered by
default. Moreover, the set of default listeners can change from release
to release, and with the support for automatic discovery of default
listeners introduced in SPR-11466 it is no longer even possible to know
what the set of default TestExecutionListeners is before runtime.
This commit addresses this issue by introducing a mechanism for merging
custom declared listeners with the defaults for the current
environment. Specifically, @TestExecutionListeners supports a new
MergeMode that is used to control whether or not explicitly declared
listeners are merged with the default listeners when
@TestExecutionListeners is declared on a class that does not inherit
listeners from a superclass.
Issue: SPR-8854
Prior to this commit, there was no declarative mechanism for a custom
TestExecutionListener to be registered as a default
TestExecutionListener.
This commit introduces support for discovering default
TestExecutionListener implementations via the SpringFactoriesLoader
mechanism. Specifically, the spring-test module declares all core
default TestExecutionListeners under the
org.springframework.test.context.TestExecutionListener key in its
META-INF/spring.factories properties file, and third-party frameworks
and developers can contribute to the list of default
TestExecutionListeners in the same manner.
- AbstractTestContextBootstrapper uses the SpringFactoriesLoader to
look up the class names of all registered default
TestExecutionListeners and sorts the instantiated listeners using
AnnotationAwareOrderComparator.
- DefaultTestContextBootstrapper and WebTestContextBootstrapper now
rely on the SpringFactoriesLoader mechanism for finding default
TestExecutionListeners instead of hard coding fully qualified class
names.
- To ensure that default TestExecutionListeners are registered in the
correct order, each can implement Ordered or declare @Order.
- AbstractTestExecutionListener and all default TestExecutionListeners
provided by Spring now implement Ordered with appropriate values.
- Introduced "copy constructors" in MergedContextConfiguration and
WebMergedContextConfiguration
- SpringFactoriesLoader now uses AnnotationAwareOrderComparator
instead of OrderComparator.
Issue: SPR-11466
Prior to this commit, if both locations and classes were declared via
@ContextConfiguration at differing levels in a test class hierarchy,
the exception message stated that neither of the default context
loaders was able to load an ApplicationContext from the merged context
configuration, but the message didn't explain why.
This commit adds an explicit check for such scenarios and provides a
more informative exception message similar to the following:
"Neither X nor Y supports loading an ApplicationContext from
[MergedContextConfiguration ...]: declare either 'locations' or
'classes' but not both."
Issue: SPR-12060
Spring Framework 3.1 introduced an Environment abstraction with support
for hierarchical PropertySources that can be configured
programmatically as well as declaratively via the @PropertySource
annotation. However, prior to this commit, there was no way to
declaratively configure PropertySources in integration tests in the
Spring TestContext Framework (TCF).
This commit introduces declarative support for PropertySources in the
TCF via a new class-level @TestPropertySource annotation. This
annotation provides two options for declaring test property sources:
- The 'locations' attribute allows developers to declare external
resource locations for test properties files.
- The 'properties' attribute allows developers to declare inlined
properties in the form of key-value pairs.
Test properties files are added to the Environment before all other
property sources and can therefore override system and application
property sources. Similarly, inlined properties are added to the
Environment before all other property sources and can therefore
override system property sources, application property sources, and
test properties files.
Specifically, this commit introduces the following major changes:
- Introduced @TestPropertySource annotation along with internal
TestPropertySourceAttributes, MergedTestPropertySources, and
TestPropertySourceUtils for working with test property sources
within the TCF.
- All TestContextBootstrappers have been modified to support the
merged property resource locations and inlined properties from
@TestPropertySource.
- MergedContextConfiguration (and consequently the context caching
key) is now additionally based on the merged property resource
locations and inlined properties from @TestPropertySource. The same
applies to WebMergedContextConfiguration.
- AbstractContextLoader's prepareContext() method now adds
PropertySources for all resource locations and inlined properties
from the supplied MergedContextConfiguration to the Environment of
the supplied ApplicationContext. All subclasses of
AbstractGenericContextLoader and AbstractGenericWebContextLoader
therefore automatically provide support for @TestPropertySource.
Issue: SPR-12051
Replace references to the old RFC 2616 (HTTP 1.1) with references
to the new RFCs 7230 to 7235.
This commit also deprecates:
- HttpStatus.USE_PROXY
- HttpStatus.REQUEST_ENTITY_TOO_LARGE in favor of HttpStatus.PAYLOAD_TOO_LARGE
- HttpStatus.REQUEST_URI_TOO_LONG in favor of HttpStatus.URI_TOO_LONG
Issue: SPR-12067
Surprisingly until now the MockMvcRequestBuilders did not have methods
for HTTP HEAD. This change adds such methods to the API making it
consistent with other HTTP method types.
Issue: SPR-12055
This commit updates the Javadoc for getLocale() and getLocales() in
MockHttpServletRequest to point out that the mock implementation does
not comply with the the Servlet specification with regard to the
Accept-Language header.
Issue: SPR-12043
This commit updates the class-level Javadoc for MockHttpServletRequest
with information regarding the default locale for the mocked server.
Issue: SPR-11701
If a resource location in the MergedContextConfiguration has a ".xml"
extension, the GenericGroovyXmlContextLoader now delegates to a
dedicated XmlBeanDefinitionReader for loading bean definitions from that
resource, thus preserving XML validation for all XML resource locations.
For all other extensions (presumably only ".groovy"), the
GenericGroovyXmlContextLoader delegates to a GroovyBeanDefinitionReader.
Issue: SPR-11233
Spring Framework 4.0 introduced first-class support for a Groovy-based
DSL for defining the beans for an ApplicationContext. However, prior to
this commit, the Spring TestContext Framework (TCF) did not provide any
out-of-the-box support for using Groovy scripts as path-based resource
locations when loading an application context for tests.
This commit addresses this issue by introducing first-class support for
using Groovy scripts to load the ApplicationContext for integration
tests managed by the TCF. Specifically, the following changes have been
made in the TCF to support Groovy scripts.
- Introduced getResourceSuffixes() in AbstractContextLoader in order
to support multiple resource suffixes in the default detection
process. This feature is used by the new Groovy/Xml context loaders.
- Introduced GenericGroovyXmlContextLoader and
GenericGroovyXmlWebContextLoader which support both Groovy scripts
and XML config files for loading bean definitions. Furthermore,
these loaders support "-context.xml" and "Context.groovy" as
resource suffixes when detecting defaults. Note that a default XML
config file will be detected before a default Groovy script.
- DelegatingSmartContextLoader and WebDelegatingSmartContextLoader now
use reflection to choose between using GenericGroovyXmlContextLoader
and GenericGroovyXmlWebContextLoader vs. GenericXmlContextLoader and
GenericXmlWebContextLoader as their XML loaders, depending on
whether Groovy is present in the classpath.
- Groovy scripts can be configured via the 'locations' or 'value'
attributes of @ContextConfiguration and can be mixed seamlessly with
XML config files.
Issue: SPR-11233
This is a follow-up on the commit introducing MockMvcConfigurer:
c2b0fac852
This commit refines the MockMvcConfigurer contract to use (the new)
ConfigurableMockMvcBuilder hence not requiring downcasting to
AbstractMockMvcBuilder.
The same also no longer passes the "default" RequestBuilder which would
also require a downcast, but rather allows a RequestPostProcessor to be
returned so that a 3rd party framework or application can modify any
property of every performed MockHttpServletRequest.
To make this possible the new SmartRequestBuilder interface separates
request building from request post processing while the new
ConfigurableSmartRequestBuilder allows adding a RequestPostProcessor
to a MockMvcBuilder.
Issue: SPR-11497
Prior to this commit, the support for SQL script execution via @Sql
provided an algorithm for looking up a required
PlatformTransactionManager to use to drive transactions. However, a
transaction manager is not actually required for all testing scenarios.
This commit improves the transaction management support for @Sql so
that SQL scripts can be executed without a transaction if a transaction
manger is not present in the ApplicationContext. The updated algorithm
now supports the following use cases.
- If a transaction manager and data source are both present (i.e.,
explicitly specified via the transactionManager and dataSource
attributes of @SqlConfig or implicitly discovered in the
ApplicationContext based on conventions), both will be used.
- If a transaction manager is not explicitly specified and not
implicitly discovered based on conventions, SQL scripts will be
executed without a transaction but requiring the presence of a data
source. If a data source is not present, an exception will be thrown.
- If a data source is not explicitly specified and not implicitly
discovered based on conventions, an attempt will be made to retrieve
it by using reflection to invoke a public method named
getDataSource() on the transaction manager. If this attempt fails,
an exception will be thrown.
- If a data source can be retrieved from the resolved transaction
manager using reflection, an exception will be thrown if the
resolved data source is not the data source associated with the
resolved transaction manager. This helps to avoid possibly
unintended configuration errors.
- If @SqlConfig.transactionMode is set to ISOLATED, an exception will
be thrown if a transaction manager is not present.
Issue: SPR-11911