Question

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>
Was it helpful?

Solution

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top