Can anyone point me to an example of how to use ServletUnit to test JSP\'s? Do I need I need to call registerServlet()? If so, what class name do I pass?
This is what I´m using now for testing JSP render and verify forms and forwards.
First Maven dependencies
net.sourceforge.openutils
openutils-testing4web
1.2.1
test
slf4j-log4j12
org.slf4j
spring-core
org.springframework
spring-context
org.springframework
slf4j-api
org.slf4j
jcl-over-slf4j
org.slf4j
jsp-api
javax.servlet
jasper-runtime
tomcat
jasper-compiler
tomcat
jasper-compiler-jdt
tomcat
org.apache.tomcat
catalina
${tomcat.version}
test
org.apache.tomcat
servlet-api
${tomcat.version}
test
org.apache.tomcat
jasper
${tomcat.version}
test
org.apache.tomcat
jasper-el
${tomcat.version}
test
org.apache.tomcat
jsp-api
${tomcat.version}
provided
javax.servlet
javax.servlet-api
${javax.servlet.version}
test
org.apache.tomcat
jasper-jdt
6.0.29
test
tomcat.version is 6.0.39 you feel free to try modern tomcat version, 7 or 8 but be care about dependencies sometimes becomes a bit fuzzy.
javax.servlet.version is 3.0.1
Next I've defined a common testing class which are extended by all my testings. I have a testing class per controller.
import it.openutils.testing.junit.AbstractDbUnitJunitSpringContextTests;
import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.core.io.Resource;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.springframework.transaction.annotation.Transactional;
import com.meterware.servletunit.ServletRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/integration/application-database-test.xml", "/integration/mvc-dispatcher-servlet-test.xml" })
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class })
public abstract class ControllerIntegrationCommonTest extends AbstractDbUnitJunitSpringContextTests
{
/**
* The Web CLient for JSP rendeting Test
*/
protected ServletRunner servletRunner;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception
{
Resource web = this.applicationContext.getResource("/WEB-INF/web.xml");
if (servletRunner == null)
{
servletRunner = new ServletRunner(web.getFile(),null);
}
}
@After
public void setDown() throws Exception
{
servletRunner.shutDown();
}
}
The @ContextConfiguration, @TestExecutionListeners are needed if you want to run it all from Spring Junit context, if you delete then you will get a nice java.lang.IllegalStateException : Failed to load ApplicationConext.
Notice here that I instantiate the ServletRunner using a Web.xml. This is mandatory of course and very similar to my production one. The second parameter, the contextPath is set to Null. For my testing I don't needed. I refer you to the API for more complete info.
Once you have that configured, make the test is easy. I add to examples:
PostMethodWebRequest webRequest = new PostMethodWebRequest("http://myserver/setup/checkXML",true);
webRequest.setParameter("param1", "11112");
File file = new File("src/test/resources/datasets/myxml.xml");
webRequest.selectFile("fileData",file,"multipart/form-data");
WebResponse webResponse = servletRunner.getResponse(webRequest);
assertNotNull(webResponse);
assertTrue(webResponse.getURL().getPath().contains("checkXML"));
assertNotNull(webResponse.getElementsByTagName("resultCheck"));
log.debug(" ----------------- ");
log.debug(webResponse.getText());
log.debug(" ----------------- ");
webResponse.getFormWithID("resultsForm").getSubmitButtons()[0].click();
In this example I will make a Post uploading a file. You need to create the PostMethodWebRequest with the parameter mimeencoded set as true. If no, you will get some funny error messages. For add the file just only used the methods. You can see in the API you can upload one file or a set of.
This last example is just for make Get request
GetMethodWebRequest webRequest = new GetMethodWebRequest("http://myserver/setup/addarea");
webRequest.setParameter("param", "11");
WebResponse webResponse = servletRunner.getResponse(webRequest);
assertNotNull(webResponse);
assertTrue(webResponse.getURL().getPath().contains("addsomething"));
assertNotNull(webResponse.getElementsByTagName("listofsomething"));
assertNotNull(webResponse.getElementsByTagName("someelement"));
log.debug(" ----------------- ");
log.debug(webResponse.getText());
log.debug(" ----------------- ");
In this example I make a Get request to my controller. As in the previous on, I send some parameters and then get the Response. There I check if the URL is what I expected and verify the JSP has render some elements.
Notice that for build the WebRequest I must use a well format URL but no problem about server name, Servlet Unit not use it at all you don't need to define in in any place.
I hope it helps you. Have fun!!