0

Background

I'm trying to implement integration test for controller in Spring. I DON'T want to use WebApplicationInitializer (Java config for Spring) to run my web app. I want to use xml based configurations. However, @ContextConfiguration could not load web.xml, so I created application-context.xml. The problem is web.xml and application-context.xml are serving the same purpose,

Question

Can I remove web.xml in favor of application-context.xml? If I remove web.xml, the test would pass, but the web app won't run in Tomcat.

Codes

This is my test class:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"file:path/to/application-context.xml"})
@WebAppConfiguration
public class HelloControllerIntegrationTest {

    @Autowired
    private WebApplicationContext context;

    private WebClient webClient;

    @Before
    public void setup() throws Exception {
        MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();

        webClient = new WebClient();
        webClient.setWebConnection(new MockMvcWebConnection(mockMvc));
    }

    @Test
    public void testPrintWelcome() throws Exception {
        // I'm trying to print out the page for now
        UnexpectedPage welcomePage = webClient.getPage("http://localhost/");
        InputStream is = welcomePage.getInputStream();
        java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
        String a = s.hasNext() ? s.next() : "";
        System.out.println(a);
    }
}

This is my application-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/mvc
                           http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context-3.2.xsd">

    <mvc:annotation-driven/>

    <mvc:default-servlet-handler/>

    <context:component-scan base-package="com.company.controller"/>

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    </bean>
</beans>
Daiwei
  • 40,666
  • 3
  • 38
  • 48
  • Does the code from your test as has been shown pass or not? Spring MVC test has nothing to do with whether or not you use web.xml to initialize the application, since it never starts the application in the servlet container. – geoand May 14 '14 at 20:04
  • @geoand yes, all tests pass. No exception was throwed. – Daiwei May 15 '14 at 06:31

1 Answers1

4

What you need to understand is that web.xml and application-context.xml serve two completely different purposes.

The first one is used to configure an application to run in a servlet container while the second one is used in order to provide Spring configuration. web.xml can of course be replaced by Java based configuration when the container supports servlet spec 3.0 or later.

When running a Spring MVC test in order to test a Spring controller, web.xml is not used at all, since the test is not run in a servlet container because the test framework mocks out all the dependencies. You could easily have Spring MVC tests for code that pass, but not have a web.xml at all if you are in a TDD environment.

In conclusion, the concerns addressed by web.xml and application-context.xml are orthogonal and one can be used without caring about the other.

Also to clarify, the configuration supplied by web.xml or the WebApplicationInitializer alternative cannot be supplied in application-context.xml

geoand
  • 60,071
  • 24
  • 172
  • 190
  • But I have to maintain two set of the same configurations in `web.xml` and `application-context.xml`, which is not what I wanted. I want to find a way so servlet container can recognizes `application-context.xml` and run without `web.xml`. – Daiwei May 16 '14 at 04:57
  • When running in a regular server environment, Spring needs to be bootstraped. That can either be done in `web.xml` or `WebApplicationInitializer`. For running Spring MVC tests, it doesn't matter since the environment is mocked and you only need to reference the Spring configuration – geoand May 16 '14 at 05:57
  • that is to say I have to use `web.xml` or `WebApplicationInitializer`, no other options. It can't be `application-context.xml`, right? If so and you want to change your answer, then I mark your answer right. Thanks. – Daiwei May 16 '14 at 14:02
  • No problem! I updated an answer with a clarification at the end – geoand May 16 '14 at 14:05