Testing Spring XmlWebApplicationContext Mappings

With XmlWebApplicationContext, file paths get resolved beneath the root of the web application. Even if a given path starts with a slash, it will get interpreted as relative to the web application root directory.

This can be problematic if you have a servlet.xml in a different module. For example if you need to include PROJECT/web/WEB-INF/my-servlet.xml you could add it to the classpath. But that’s not possible if you exclude the “PROJECT/web” directory from the module you’re testing.

FileSystemApplicationContext works differently. It adds paths relative to the project directory.

Here’s what ended up working for me:

public MyTestCase() {
    ctx = new XmlWebApplicationContext(){
        /**
         * Add the ability to read relative FileSystemPaths
         * @see org.springframework.web.context.support.XmlWebApplicationContext#getResourceByPath
         */
        protected Resource getResourceByPath(String path) {
            if(path.startsWith("classpath:")) return super.getResourceByPath(path);
            //Copied from @see org.springframework.web.context.support.FileSystemApplicationContext#getResourceByPath
            if (path != null && path.startsWith("/")) {
                path = path.substring(1);
            }
            return new FileSystemResource(path);
        }
    };
    ctx.setConfigLocations(new String[]{"classpath:applicationContext.xml", "/web/WEB-INF/my-servlet.xml"});
    ctx.setServletContext(new MockServletContext("/"));
    ctx.refresh();
    handlerMapping = (HandlerMapping) ctx.getBean("urlMapping");
}

void assertCorrectController(String path, String controller) throws Exception {
    HandlerExecutionChain hec = handlerMapping.getHandler(new MockHttpServletRequest("GET", path));
    assertTrue(hec != null);
    assertEquals(hec.getHandler(), ctx.getBean(controller));
}

Now I can do the following test:

public void testSeasonControllerMapping() throws Exception {
    assertCorrectController("/my/season", "seasonController");
}

admin