Prior to this commit the Spring TestContext Framework supported creating
only flat, non-hierarchical contexts. There was no easy way to create
contexts with parent-child relationships.
This commit addresses this issue by introducing a new @ContextHierarchy
annotation that can be used in conjunction with @ContextConfiguration
for declaring hierarchies of application contexts, either within a
single test class or within a test class hierarchy. In addition,
@DirtiesContext now supports a new 'hierarchyMode' attribute for
controlling context cache clearing for context hierarchies.
- Introduced a new @ContextHierarchy annotation.
- Introduced 'name' attribute in @ContextConfiguration.
- Introduced 'name' property in ContextConfigurationAttributes.
- TestContext is now aware of @ContextHierarchy in addition to
@ContextConfiguration.
- Introduced findAnnotationDeclaringClassForTypes() in AnnotationUtils.
- Introduced resolveContextHierarchyAttributes() in ContextLoaderUtils.
- Introduced buildContextHierarchyMap() in ContextLoaderUtils.
- @ContextConfiguration and @ContextHierarchy may not be used as
top-level, class-level annotations simultaneously.
- Introduced reference to the parent configuration in
MergedContextConfiguration and WebMergedContextConfiguration.
- Introduced overloaded buildMergedContextConfiguration() methods in
ContextLoaderUtils in order to handle context hierarchies separately
from conventional, non-hierarchical contexts.
- Introduced hashCode() and equals() in ContextConfigurationAttributes.
- ContextLoaderUtils ensures uniqueness of @ContextConfiguration
elements within a single @ContextHierarchy declaration.
- Introduced CacheAwareContextLoaderDelegate that can be used for
loading contexts with transparent support for interacting with the
context cache -- for example, for retrieving the parent application
context in a context hierarchy.
- TestContext now delegates to CacheAwareContextLoaderDelegate for
loading contexts.
- Introduced getParentApplicationContext() in MergedContextConfiguration
- The loadContext(MergedContextConfiguration) methods in
AbstractGenericContextLoader and AbstractGenericWebContextLoader now
set the parent context as appropriate.
- Introduced 'hierarchyMode' attribute in @DirtiesContext with a
corresponding HierarchyMode enum that defines EXHAUSTIVE and
CURRENT_LEVEL cache removal modes.
- ContextCache now internally tracks the relationships between contexts
that make up a context hierarchy. Furthermore, when a context is
removed, if it is part of a context hierarchy all corresponding
contexts will be removed from the cache according to the supplied
HierarchyMode.
- AbstractGenericWebContextLoader will set a loaded context as the
ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE in the MockServletContext when
context hierarchies are used if the context has no parent or if the
context has a parent that is not a WAC.
- Where appropriate, updated Javadoc to refer to the
ServletTestExecutionListener, which was introduced in 3.2.0.
- Updated Javadoc to avoid and/or suppress warnings in spring-test.
- Suppressed remaining warnings in code in spring-test.
Issue: SPR-5613, SPR-9863
Prior to this commit many test utility classes and sample beans were
duplicated across projects. This was previously necessary due to the
fact that dependent test sources were not shared during a gradle
build. Since the introduction of the 'test-source-set-dependencies'
gradle plugin this is no longer the case.
This commit attempts to remove as much duplicate code as possible,
co-locating test utilities and beans in the most suitable project.
For example, test beans are now located in the 'spring-beans'
project.
Some of the duplicated code had started to drift apart when
modifications made in one project where not ported to others. All
changes have now been consolidated and when necessary existing tests
have been refactored to account for the differences.
Conflicts:
spring-beans/src/test/java/org/springframework/beans/factory/ConcurrentBeanFactoryTests.java
spring-beans/src/test/java/org/springframework/beans/factory/support/BeanFactoryGenericsTests.java
spring-beans/src/test/java/org/springframework/beans/support/PagedListHolderTests.java
When Spr9799XmlConfigTests and Spr9799AnnotationConfigTests were
created, there were issues with the classpath related to slf4j
dependencies that made it impossible for these classes to reside in the
spring-test module. Consequently, these tests were added to the
spring-test-mvc module. However, the issues with slf4j have since been
resolved in the Gradle build, and this commit therefore moves these test
classes to the spring-test module where they belong.
Issue: SPR-9799
Prior to this commit, executing an SQL script with JdbcTestUtils would
fail if a statement in the script contained a line comment within the
statement.
This commit ensures that standard SQL comments (i.e., any text beginning
with two hyphens and extending to the end of the line) are properly
omitted from the statement before executing it.
In addition, multiple adjacent whitespace characters within a statement
but outside a literal are now collapsed into a single space.
Issue: SPR-9982
Prior to this commit, utility methods in JdbcTestUtils interpreted SQL
comments as separate statements, resulting in an exception when such a
script is executed.
This commit addresses this issue by introducing a
readScript(lineNumberReader, String) method that accepts a comment
prefix. Comment lines are therefore no longer returned in the parsed
script. Furthermore, the existing readScript(lineNumberReader) method
now delegates to this new readScript() method, supplying "--" as the
default comment prefix.
Issue: SPR-9593
This commit introduces RequestAndSessionScopedBeansWacTests which
verifies support for request and session scoped beans in the Spring
TestContext Framework (TCF).
This support was actually introduced as an intentional side effect of
the work performed for SPR-5243 through the addition of the new
WebTestExecutionListener.
Issue: SPR-4588
Prior to this commit, the Spring TestContext Framework only supported
loading an ApplicationContext in integration tests from either XML or
Java Properties files (since Spring 2.5), and Spring 3.1 introduced
support for loading an ApplicationContext in integration tests from
annotated classes (e.g., @Configuration classes). All of the
ContextLoader implementations used to provide this support load a
GenericApplicationContext. However, a GenericApplicationContext is not
suitable for testing a web application since a web application relies on
an implementation of WebApplicationContext (WAC).
This commit makes it possible to integration test Spring-powered web
applications by adding the following functionality to the Spring
TestContext Framework.
- Introduced AbstractGenericWebContextLoader and two concrete
subclasses:
- XmlWebContextLoader
- AnnotationConfigWebContextLoader
- Pulled up prepareContext(context, mergedConfig) from
AbstractGenericContextLoader into AbstractContextLoader to allow it
to be shared across web and non-web context loaders.
- Introduced AnnotationConfigContextLoaderUtils and refactored
AnnotationConfigContextLoader accordingly. These utils are also used
by AnnotationConfigWebContextLoader.
- Introduced a new @WebAppConfiguration annotation to denote that the
ApplicationContext loaded for a test should be a WAC and to configure
the base resource path for the root directory of a web application.
- Introduced WebMergedContextConfiguration which extends
MergedContextConfiguration with support for a baseResourcePath for
the root directory of a web application.
- ContextLoaderUtils.buildMergedContextConfiguration() now builds a
WebMergedContextConfiguration instead of a standard
MergedContextConfiguration if @WebAppConfiguration is present on the
test class.
- Introduced a configureWebResources() method in
AbstractGenericWebContextLoader that is responsible for creating a
MockServletContext with a proper ResourceLoader for the
resourceBasePath configured in the WebMergedContextConfiguration. The
resulting mock ServletContext is set in the WAC, and the WAC is
stored as the Root WAC in the ServletContext.
- Introduced a WebTestExecutionListener that sets up default thread
local state via RequestContextHolder before each test method by using
the MockServletContext already present in the WAC and by creating a
MockHttpServletRequest, MockHttpServletResponse, and
ServletWebRequest that is set in the RequestContextHolder. WTEL also
ensures that the MockHttpServletResponse and ServletWebRequest can be
injected into the test instance (e.g., via @Autowired) and cleans up
thread locals after each test method.
- WebTestExecutionListener is configured as a default
TestExecutionListener before DependencyInjectionTestExecutionListener
- Extracted AbstractDelegatingSmartContextLoader from
DelegatingSmartContextLoader and introduced a new
WebDelegatingSmartContextLoader.
- ContextLoaderUtils now selects the default delegating ContextLoader
class name based on the presence of @WebAppConfiguration on the test
class.
- Tests in the spring-test-mvc module no longer use a custom
ContextLoader to load a WebApplicationContext. Instead, they now
rely on new core functionality provided in this commit.
Issue: SPR-5243
TransactionalTestExecutionListener currently requires that the
PlatformTransactionManager bean be named "transactionManager" by
default. Otherwise, the bean name can only be overridden via the
transactionManager attribute of @TransactionConfiguration or the value
attribute of @Transactional.
However, if there is only a single PlatformTransactionManager in the
test's ApplicationContext, then the requirement to specify the exact
name of that bean (or to name it exactly "transactionManager") is often
superfluous.
This commit addresses this issue by refactoring the
TransactionalTestExecutionListener so that it is comparable to the
algorithm for determining the transaction manager used in
TransactionAspectSupport for "production" code. Specifically, the TTEL
now uses the following algorithm to retrieve the transaction manager.
- look up by type and qualifier from @Transactional
- else, look up by type and explicit name from
@TransactionConfiguration
- else, look up single bean by type
- else, look up by type and default name from @TransactionConfiguration
Issue: SPR-9645
Currently the getNamedDispatcher(String) method of MockServletContext
always returns null. This poses a problem in certain testing scenarios
since one would always expect at least a default Servlet to be present.
This is specifically important for web application tests that involve
the DefaultServletHttpRequestHandler which attempts to forward to the
default Servlet after retrieving it by name. Furthermore, there is no
way to register a named RequestDispatcher with the MockServletContext.
This commit addresses these issues by introducing the following in
MockServletContext.
- a new defaultServletName property for configuring the name of the
default Servlet, which defaults to "default"
- named RequestDispatchers can be registered and unregistered
- a MockRequestDispatcher is registered for the "default" Servlet
automatically in the constructor
- when the defaultServletName property is set to a new value the
the current default RequestDispatcher is unregistered and replaced
with a MockRequestDispatcher for the new defaultServletName
Issue: SPR-9587
AbstractTransactionalAnnotatedConfigClassTests is now annotated with
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) so
that side-effects between tests are avoided.
Re-enabled TransactionalAnnotatedConfigClassWithAtConfigurationTests
and TransactionalAnnotatedConfigClassesWithoutAtConfigurationTests.
Also introduced a log4j FileAppender for tests that writes to
"build/spring-test.log".
Issue: SPR-9051
This renaming more intuitively expresses the relationship between
subprojects and the JAR artifacts they produce.
Tracking history across these renames is possible, but it requires
use of the --follow flag to `git log`, for example
$ git log spring-aop/src/main/java/org/springframework/aop/Advisor.java
will show history up until the renaming event, where
$ git log --follow spring-aop/src/main/java/org/springframework/aop/Advisor.java
will show history for all changes to the file, before and after the
renaming.
See http://chrisbeams.com/git-diff-across-renamed-directories