-
Notifications
You must be signed in to change notification settings - Fork 38.4k
Support loading WebApplicationContexts with the TestContext Framework [SPR-5243] #9917
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Narada Sage commented I would absolutely love this. I've spent a lot of time trying to get this to work. It shouldn't be this difficult. It'd be great if this not uncommon use case was available out of the box. Thanks. |
Gaetan Pitteloud commented Loading a WebApplicationContext is not a difficult task on its own : you just provide a I have built a solution based on a test listener (so-called WebListener) that creates the web environment (based on spring mock classes) : Mock ServletContext, Mock request, response, session. The ServletContext is created once (beforeTestClass) for a test class, and is <i>injected</i> into the ContextLoader (there's no API to do this, thus I had to do it with reflexion, which is the goal of my TestContextUtils class). I have to ensure that the context is not loaded yet, or this trick will not work (I mark it as dirty for that purpose, and also because it might have been loaded by another test class earlier, or will be used by another test class later on). You will find attached the WebListener and Web ContextLoader that are working together. The web listener's duty also includes a way to inject the web mocks (ServletContext, request, response, etc.) into test instance variables that are annotated with The WebListener is actually split into an AbstractWebListener and its subclass WebListener because I also implemented a JsfListener with the same semantics, with the only jsf mock lib I found so far : shale-test. There are tests in the listener that test for the existence of an application context (by looking for a The mock objects (request, response, session) are shared for other listeners to use thanks to TestContext internal attributes map, which also happens to be useful. |
Stevo Slavić commented Checkout Spring MVC integration test support Rosen and Arjen have been building @ https://github.com/SpringSource/spring-test-mvc |
Rossen Stoyanchev commented The two might be quite complementary. You could use this to create and initialize a WebApplicationContext once per test fixture and then provide it to the main class of the Spring MVC integration test support. |
Sam Brannen commented If you are watching this issue, please feel free to participate in the discussion regarding the proposed Deliverables and the corresponding Pseudocode Examples listed in this issue's Description. Thanks! Sam |
Gaetan Pitteloud commented 2 comments:
And 2 questions:
|
Sam Brannen commented Hi Gaetan,
One of the key features of the TestContext framework is caching. Thus the WAC will certainly be cached by default. Please note that the proposed subclass of Why do you say that "the lifespan of its ServletContext is limited to the test class"? I would argue that the lifespan of the If you want to disable caching of a WAC after a particular test class, simply annotate the test class with
How do you propose to inject the mocks if not from a configured WAC? Are you proposing to just have a custom Can you please provide some pseudocode to demonstrate your use case?
No, there is currently no plan to support this, but it is an interesting idea. So feel free to create a separate JIRA issue to request it.
The code needed to support the features in this issue will be integrated in the TestContext framework, tentatively including two Regards, Sam |
Gaetan Pitteloud commented Hi Sam, Thanks for the reply and explanations. Regarding caching, I was thinking about a first test with a plain ApplicationContext and a second test with a WebApplicationContext, both defined with similar xml locations. Using current caching facility (key=xml locations), both contexts would be stored under same key.
You're right, the lifespan of the Regarding web tests without WAC, a simple TestExecutionListener can do the job :
This helps writing tests for a POJO web controller that does not need application context infrastructure, but just access to a request/response pair and maybe a user session. With such a listener, there's no need to write a Regarding security, I created the issue SEC-2015. Regards, |
Sam Brannen commented This issue depends on #10284 in order to support common context hierarchies in Spring MVC web applications. |
Rossen Stoyanchev commented
The spring-test-mvc project (to be included in Spring 3.2) might fit this description. The "standalone" setup does not require an ApplicationContext and uses the mock request/response internally. See this example as well as many others in that package and sub-packages. |
Sam Brannen commented If you're following this issue, you may interested in knowing that support for Regards, Sam |
Sam Brannen commented Pull request submitted: #160 |
Sam Brannen commented This work has been addressed as discussed in the comments for GitHub commit 9937f840d5:
|
Sam Brannen commented Note that |
Geoff Metselaar opened SPR-5243 and commented
Status Quo
When the Spring TestContext Framework was introduced in Spring 2.5, it supported loading an
ApplicationContext
from either XML or Java Properties files. Spring 3.1 introduced support for loading anApplicationContext
from annotated classes (e.g.,@Configuration
classes).The underlying implementation for the existing support creates a
GenericApplicationContext
; however, aGenericApplicationContext
is not suitable for testing a web application since a web application relies on an implementation ofWebApplicationContext
(WAC).In order to integration test Spring-powered web applications the Spring TestContext Framework needs to be able to load a
WebApplicationContext
, either from XML configuration files or from annotated classes. Furthermore, theServletContext
used by such a WAC needs to be configurable within tests, and common context hierarchies must be supported (e.g., root and dispatcher WACs in a parent-child relationship).Original Author's Description
While writing some MVC integration tests, context errors were thrown when loading an
XmlViewResolver
and when attempting to recover command object property validation errors using theRequestContext
. The reason is that each of these requires access to aWebApplicationContext
, not aGenericApplicationContext
which the TestContext framework makes available by default.Goals
ServletContext
from within integration tests.SmartContextLoaders
that can loadWebApplicationContexts
from either XML or annotated classes, using the configured mockServletContext
.HttpServletRequest
andHttpServletResponse
objects and ensure that thread-local state in Spring MVC is kept in sync with these mock objects.WebApplicationContext
(e.g.,ServletContext
path) is used to define the unique application context cache key.Deliverables
SmartContextLoader
that loads aWebApplicationContext
from XML resource locations defined via@ContextConfiguration
SmartContextLoader
that loads aWebApplicationContext
from annotated classes defined via@ContextConfiguration
@WebAppConfiguration
annotation that allows for configuration of theServletContext
base resource path, using Spring'sResource
abstractionContextMockMvcBuilder.configureWebAppRootDir()
fromspring-test-mvc
locations
attribute in@ContextConfiguration
which is classpath-based@WebAppConfiguration
should be inherited (i.e., annotated with@Inherited
), keeping in mind that the top-level context in an EAR would not be a WACSmartContextLoader
implementations create aMockServletContext
on demand (i.e., if a root WAC), when the WAC is loaded, and set theMockServletContext
as theServletContext
in the application contexts that they loadROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
in theMockServletContext
when context hierarchies are not usedMergedContextConfiguration
specific for web apps (e.g.,WebMergedContextConfiguration
) that stores theServletContext
base pathequals()
andhashCode()
to include the metadata that uniquely identifies the resulting WAC for proper context cachingbuildMergedContextConfiguration()
method inContextLoaderUtils
will likely need to instantiate either a standardMergedContextConfiguration
or aWebMergedContextConfiguration
RequestContextHolder
before each test method by implementing a new Servlet-specificTestExecutionListener
MockServletContext
already present in the WAC and by creating aMockHttpServletRequest
,MockHttpServletResponse
, andServletWebRequest
which will be set in theRequestContextHolder
MockServletContext
,MockHttpServletRequest
,MockHttpServletResponse
, andServletWebRequest
can be injected into the test instance (e.g., via@Autowired
)TestExecutionListener
is configured as a defaultTestExecutionListener
beforeDependencyInjectionTestExecutionListener
DelegatingSmartContextLoader
to incorporate support for theSmartContextLoader
types introduced in this issue and ensure that the correct delegating loader is picked based on the presence or absence of@WebAppConfiguration
Pseudocode Examples
Root WAC with Injected Mocks
Further Resources
Blogs and Custom Solutions
Forum Discussions
Affects: 2.5 final, 3.0 GA, 3.1 GA
Attachments:
Issue Links:
@ContextConfiguration
that creates a WebApplicationContext ("is duplicated by")Referenced from: commits 461d99a, a281bdb, 90c5f22, 9937f84, a73280c, 21ebbb9
30 votes, 29 watchers
The text was updated successfully, but these errors were encountered: