Support loading WebApplicationContexts in the TCF
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
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -42,7 +42,7 @@ public class TestExecutionListenersTests {
|
||||
@Test
|
||||
public void verifyNumDefaultListenersRegistered() throws Exception {
|
||||
TestContextManager testContextManager = new TestContextManager(DefaultListenersExampleTestCase.class);
|
||||
assertEquals("Verifying the number of registered TestExecutionListeners for DefaultListenersExampleTest.", 3,
|
||||
assertEquals("Verifying the number of registered TestExecutionListeners for DefaultListenersExampleTest.", 4,
|
||||
testContextManager.getTestExecutionListeners().size());
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.context.web;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.web.context.ServletContextAware;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
|
||||
/**
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@WebAppConfiguration
|
||||
public abstract class AbstractBasicWacTests implements ServletContextAware {
|
||||
|
||||
protected ServletContext servletContext;
|
||||
|
||||
@Autowired
|
||||
protected WebApplicationContext wac;
|
||||
|
||||
@Autowired
|
||||
protected MockServletContext mockServletContext;
|
||||
|
||||
@Autowired
|
||||
protected MockHttpServletRequest request;
|
||||
|
||||
@Autowired
|
||||
protected MockHttpServletResponse response;
|
||||
|
||||
@Autowired
|
||||
protected ServletWebRequest webRequest;
|
||||
|
||||
@Autowired
|
||||
protected String foo;
|
||||
|
||||
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
this.servletContext = servletContext;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basicWacFeatures() throws Exception {
|
||||
assertNotNull("ServletContext should be set in the WAC.", wac.getServletContext());
|
||||
|
||||
assertNotNull("ServletContext should have been set via ServletContextAware.", servletContext);
|
||||
|
||||
assertNotNull("ServletContext should have been autowired from the WAC.", mockServletContext);
|
||||
assertNotNull("MockHttpServletRequest should have been autowired from the WAC.", request);
|
||||
assertNotNull("MockHttpServletResponse should have been autowired from the WAC.", response);
|
||||
assertNotNull("ServletWebRequest should have been autowired from the WAC.", webRequest);
|
||||
|
||||
Object rootWac = mockServletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
|
||||
assertNotNull("Root WAC must be stored in the ServletContext as: "
|
||||
+ WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, rootWac);
|
||||
assertSame("test WAC and Root WAC in ServletContext must be the same object.", wac, rootWac);
|
||||
assertSame("ServletContext instances must be the same object.", mockServletContext, wac.getServletContext());
|
||||
assertSame("ServletContext in the WAC and in the mock request", mockServletContext, request.getServletContext());
|
||||
|
||||
assertEquals("Getting real path for ServletContext resource.",
|
||||
new File("src/main/webapp/index.jsp").getCanonicalPath(), mockServletContext.getRealPath("index.jsp"));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.context.web;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
/**
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
*/
|
||||
@ContextConfiguration
|
||||
public class BasicAnnotationConfigWacTests extends AbstractBasicWacTests {
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "enigma";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void fooEnigmaAutowired() {
|
||||
assertEquals("enigma", foo);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.context.web;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
/**
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
*/
|
||||
@ContextConfiguration
|
||||
public class BasicXmlWacTests extends AbstractBasicWacTests {
|
||||
|
||||
@Test
|
||||
public void fooBarAutowired() {
|
||||
assertEquals("bar", foo);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.context.web;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
import org.springframework.test.context.ContextLoader;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
/**
|
||||
* Convenience test suite for integration tests that verify support for
|
||||
* {@link WebApplicationContext} {@linkplain ContextLoader context loaders}
|
||||
* in the TestContext framework.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
*/
|
||||
@RunWith(Suite.class)
|
||||
// Note: the following 'multi-line' layout is for enhanced code readability.
|
||||
@SuiteClasses({//
|
||||
BasicXmlWacTests.class,//
|
||||
BasicAnnotationConfigWacTests.class //
|
||||
})
|
||||
public class WebContextLoaderTestSuite {
|
||||
}
|
||||
Reference in New Issue
Block a user