andrews
Mar 22nd, 2006, 10:07 PM
Sure it's easy to write unit tests for your Java classes if you design them properly, but I also like to be able to test any pseudo-code that's in my Spring config files.
In a previous post (http://forum.springframework.org/showpost.php?p=54895&postcount=15) (http://forum.springframework.org/showpost.php?p=54895&postcount=15%29), I described how to test "URL-to-authority" mappings for a FilterInvocationDefinitionSource. Another possible point of failure is the mapping of URLs to Controllers (this assumes you use a URL-based HandlerMapping such as SimpleUrlHandlerMapping). For example, your HandlerMapping might be set up like this (I guess most people use SimpleUrlHandlerMapping?):
<bean name="urlMapper"
class="org.springframework.web.servlet.handler.SimpleUrlH andlerMapping"
>
<property name="mappings">
<props>
<prop key="/about.htm">aboutController</prop>
<prop key="/address.htm">addressController</prop>
<!-- etc. etc. -->
<prop key="/*.htm">defaultController</prop>
</props>
</property>
...
</bean>
After a bit of head-scratching, I came up with the following JUnit test that checks each URL is mapped to the correct Controller (most of this is a standard Spring functional test, the interesting bit is the assertHandlerEquals method):
package au.com.bisinfo.cmgr.functional;
import org.springframework.test.AbstractDependencyInjecti onSpringContextTests;
import org.springframework.web.servlet.HandlerExecutionCh ain;
import org.springframework.web.servlet.HandlerMapping;
import au.com.bisinfo.cmgr.client.web.controller.AboutCon troller;
import au.com.bisinfo.cmgr.client.web.controller.DefaultC ontroller;
import au.com.bisinfo.cmgr.client.web.controller.ReleaseN otesController;
import com.mockrunner.mock.web.MockHttpServletRequest;
/**
* <p>Tests that URLs are correctly mapped to controllers</p>
*/
public class UrlHandlerMappingFunctionalTest
extends AbstractDependencyInjectionSpringContextTests
{
// Constants
protected static final String
CONFIG_FILE_DAO = "classpath:WEB-INF/cmgr-dao.xml",
CONFIG_FILE_SERVICE = "classpath:WEB-INF/cmgr-services.xml",
CONFIG_FILE_SERVLET = "classpath:WEB-INF/cmgr-servlet.xml",
CONFIG_FILE_VIEW = "classpath:WEB-INF/cmgr-view.xml",
CONFIG_FILE_TEST_DB = "classpath:spring-config/test-database.xml";
// Properties
private HandlerMapping handlerMapping;
private MockHttpServletRequest request;
public void setHandlerMapping(HandlerMapping handlerMapping) {
this.handlerMapping = handlerMapping;
}
@Override
protected String[] getConfigLocations() {
return new String[] {
CONFIG_FILE_TEST_DB,
CONFIG_FILE_DAO,
CONFIG_FILE_SERVICE,
CONFIG_FILE_SERVLET,
CONFIG_FILE_VIEW
};
}
@Override
protected void onSetUp() throws Exception {
request = new MockHttpServletRequest();
super.onSetUp();
}
/**
* Asserts that the given URL maps to the given controller class
*
* @param url the URL to test
* @param expectedHandler the expected handler class; can't be
* <code>null</code>
* @throws Exception
*/
private void assertHandlerEquals(String url, Class expectedHandler)
throws Exception
{
request.setRequestURI(url);
request.setServletPath(url);
HandlerExecutionChain executionChain = handlerMapping.getHandler(request);
assertNotNull("Should be an execution chain for the URL '" + url + "'",
executionChain);
Object handler = executionChain.getHandler();
assertEquals(expectedHandler, handler.getClass());
}
public void testAbout() throws Exception {
assertHandlerEquals("/about.htm", AboutController.class);
}
public void testReleaseNotes() throws Exception {
assertHandlerEquals("/release_notes.htm", ReleaseNotesController.class);
}
public void testUnknownUrl() throws Exception {
assertHandlerEquals("/guff.htm", DefaultController.class);
}
}Hope this helps anyone who shares my "test everything" fetish...
Andrew
In a previous post (http://forum.springframework.org/showpost.php?p=54895&postcount=15) (http://forum.springframework.org/showpost.php?p=54895&postcount=15%29), I described how to test "URL-to-authority" mappings for a FilterInvocationDefinitionSource. Another possible point of failure is the mapping of URLs to Controllers (this assumes you use a URL-based HandlerMapping such as SimpleUrlHandlerMapping). For example, your HandlerMapping might be set up like this (I guess most people use SimpleUrlHandlerMapping?):
<bean name="urlMapper"
class="org.springframework.web.servlet.handler.SimpleUrlH andlerMapping"
>
<property name="mappings">
<props>
<prop key="/about.htm">aboutController</prop>
<prop key="/address.htm">addressController</prop>
<!-- etc. etc. -->
<prop key="/*.htm">defaultController</prop>
</props>
</property>
...
</bean>
After a bit of head-scratching, I came up with the following JUnit test that checks each URL is mapped to the correct Controller (most of this is a standard Spring functional test, the interesting bit is the assertHandlerEquals method):
package au.com.bisinfo.cmgr.functional;
import org.springframework.test.AbstractDependencyInjecti onSpringContextTests;
import org.springframework.web.servlet.HandlerExecutionCh ain;
import org.springframework.web.servlet.HandlerMapping;
import au.com.bisinfo.cmgr.client.web.controller.AboutCon troller;
import au.com.bisinfo.cmgr.client.web.controller.DefaultC ontroller;
import au.com.bisinfo.cmgr.client.web.controller.ReleaseN otesController;
import com.mockrunner.mock.web.MockHttpServletRequest;
/**
* <p>Tests that URLs are correctly mapped to controllers</p>
*/
public class UrlHandlerMappingFunctionalTest
extends AbstractDependencyInjectionSpringContextTests
{
// Constants
protected static final String
CONFIG_FILE_DAO = "classpath:WEB-INF/cmgr-dao.xml",
CONFIG_FILE_SERVICE = "classpath:WEB-INF/cmgr-services.xml",
CONFIG_FILE_SERVLET = "classpath:WEB-INF/cmgr-servlet.xml",
CONFIG_FILE_VIEW = "classpath:WEB-INF/cmgr-view.xml",
CONFIG_FILE_TEST_DB = "classpath:spring-config/test-database.xml";
// Properties
private HandlerMapping handlerMapping;
private MockHttpServletRequest request;
public void setHandlerMapping(HandlerMapping handlerMapping) {
this.handlerMapping = handlerMapping;
}
@Override
protected String[] getConfigLocations() {
return new String[] {
CONFIG_FILE_TEST_DB,
CONFIG_FILE_DAO,
CONFIG_FILE_SERVICE,
CONFIG_FILE_SERVLET,
CONFIG_FILE_VIEW
};
}
@Override
protected void onSetUp() throws Exception {
request = new MockHttpServletRequest();
super.onSetUp();
}
/**
* Asserts that the given URL maps to the given controller class
*
* @param url the URL to test
* @param expectedHandler the expected handler class; can't be
* <code>null</code>
* @throws Exception
*/
private void assertHandlerEquals(String url, Class expectedHandler)
throws Exception
{
request.setRequestURI(url);
request.setServletPath(url);
HandlerExecutionChain executionChain = handlerMapping.getHandler(request);
assertNotNull("Should be an execution chain for the URL '" + url + "'",
executionChain);
Object handler = executionChain.getHandler();
assertEquals(expectedHandler, handler.getClass());
}
public void testAbout() throws Exception {
assertHandlerEquals("/about.htm", AboutController.class);
}
public void testReleaseNotes() throws Exception {
assertHandlerEquals("/release_notes.htm", ReleaseNotesController.class);
}
public void testUnknownUrl() throws Exception {
assertHandlerEquals("/guff.htm", DefaultController.class);
}
}Hope this helps anyone who shares my "test everything" fetish...
Andrew