Sample on StrutsTestCase with JUnit
Now we can see example on StrutsTestCase with Eclipse. That will help the web developers to test their application in simpler way. In this article I have presented a sample which extends MockStrutsTestCase.
Suppose we have a sample for Login to an application. The test case should have various test inputs to test Login. The ActionForm will have the inputs as username and password. The test case should pass various values to the parameters username and password to validate the Login.
The following are the steps to develop an application in struts and test it with strutstestcase.
1) Download sturts framework and strutstestcase from www.sourceforge.net .
2) Download Junit jar if it is not available with your eclipse installed. Later versions of Eclipse will have Junit plugin by default.
3) Click File à New à Project à Give project name ( say StrutsTestCase )
4) Right click on your project name in Project Explorer perspective view à New à Source Folder à Give name ( say src ) or else choose from File menu.
5) Right click on project name à New à Folder à Give name ( WEB-INF ).
6) Create web.xml file by Right click on WEB-INF folder à New à File à Give name (web.xml)
7) Create struts-config.xml file by Right click on WEB-INF folder à New à File à Give name (struts-config.xml)
8) Copy necessary struts tld file to WEB-INF directory.
9) Right click on project name à New à Folder à lib. Copy necessary jar files to your lib directory.
10) Right click on project name à New à Folder à Give name ( jsp ).
11) Build classpath by Right click on project name à Build Path à configure Build Path…
12) Add necessary jars in Java Build Path option as following. Struts-1.2.jar, strutstest-2.1.4.jar , servlet-api.jar are necessary for MockStrutsTestCase.
13) Create package by Right click on src à New à Package à Give name (com.apache.struts)
14) Create java class files by Right click on package à New à Class à Give Name ( LoginAction )
15) Create java class files by Right click on package à New à Class à Give Name (LoginForm)
16) Create JunitTestCase by Right click on package à New à JUnitTestCase à Give name (LoginActionTest)
17) TestCase should extend either MockStrutsTestCase (if you are running in command prompt or eclipse) or CactusStrutsTestCase(it will need ServletEngine to run TestCase)
i) Check which method stubs you would like to create. You can create a main method, setUp(), tearDown(), or a constructor(), but all of these are optional. A constructor is only run when the test case class is first instantiated, but the setUp() and tearDown() methods are run before and after, respectively, each test case is run.
18) create jsp files by Right click on jsp à New à File àGive name (Login.jsp)
19) create jsp files by Right click on jsp à New à File àGive name (Success.jsp).
20) Run your TestCase by Right click on TestCase à Run As à JunitTestCase or Java Application.
As I have specified that JUnit has three way (textui, awtui, swingui) to run our test cases, I have used textui TestRunner for the testcases.
Note:
1) The package structure for java classes and JunitTestCase should be same.
2) Test class name should be same as Class name followed by Test.
3) Test methods should be same as specified above.
Sample Code:
LoginAction.java
package com.apache.struts;
import org.apache.struts.action.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
*
* @author subbulakshmi_g
* @web http://sites.google.com/site/suseeganesan
* @email subbuseema@gmail.com / subbu_seema@yahoo.co.in
*
*/
public class LoginAction extends Action {
private String userName;
private String password;
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
LoginForm loginForm = (LoginForm) form;
userName = loginForm.getUsername();
password = loginForm.getPassword();
ActionErrors errors = new ActionErrors();
if ((!userName.equals("struts")) || (!password.equals("apache")))
errors.add("password",new ActionMessage("error.password.mismatch"));
if (!errors.isEmpty()) {
saveErrors(request,errors);
return new ActionForward(mapping.getInput());
}
HttpSession session = request.getSession();
session.setAttribute("authentication", userName);
return mapping.findForward("success");
}
}
LoginForm.java
package com.apache.struts;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
/**
*
* @author subbulakshmi_g
* @web http://sites.google.com/site/suseeganesan
* @email subbuseema@gmail.com / subbu_seema@yahoo.co.in
*
*/
public class LoginForm extends ActionForm {
private String username;
private String password;
public void setUsername(String username) {
this.username = username;
}
public String getUsername() {
return this.username;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
}
Login.jsp
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<h2>Login Here</h2>
<h2>user="struts" and password="struts"</h2>
<html:form action="/LoginAction" >
username: <html:text property="username"/>
<br/>
password: <html:password property="password"/>
<br/>
<html:errors />
<html:submit/>
</html:form>
Success.jsp
<h2>You have successfully logged in!</h2>
<a href="/test/login/login.jsp">Go back</a>
web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<context-param>
<param-name>username</param-name>
<param-value>struts</param-value>
</context-param>
<!-- Cactus Servlet Redirector configuration -->
<servlet>
<servlet-name>ServletRedirector</servlet-name>
<servlet-class>org.apache.cactus.server.ServletTestRedirector</servlet-class>
</servlet>
<!-- Action Servlet Configuration -->
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>application</param-name>
<param-value>examples.ApplicationResources</param-value>
</init-param>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>config/tiles</param-name>
<param-value>/WEB-INF/struts-config-tiles.xml</param-value>
</init-param>
<init-param>
<param-name>config/test</param-name>
<param-value>/WEB-INF/struts-config-test.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>3</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>3</param-value>
</init-param>
<init-param>
<param-name>validating</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<!-- Cactus Servlet Redirector URL mapping -->
<servlet-mapping>
<servlet-name>ServletRedirector</servlet-name>
<url-pattern>/ServletRedirector</url-pattern>
</servlet-mapping>
<!-- Action Servlet Mapping -->
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- The Welcome File List -->
<welcome-file-list>
<welcome-file>/login/login.jsp</welcome-file>
</welcome-file-list>
<!-- Struts Tag Library Descriptors -->
<taglib>
<taglib-uri>/tags/struts-bean</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/tags/struts-html</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/tags/struts-logic</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/tags/struts-form</taglib-uri>
<taglib-location>/WEB-INF/struts-form.tld</taglib-location>
</taglib>
</web-app>
struts-config.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<struts-config>
<!-- ========== Form Bean Definitions =================================== -->
<form-beans>
<form-bean name="loginForm" type="com.apache.struts.LoginForm"/>
</form-beans>
<!-- ========== Global Forward Definitions ============================== -->
<global-forwards>
</global-forwards>
<!-- ========== Action Mapping Definitions ============================== -->
<action-mappings>
<!-- Process a user logon -->
<action path="/LoginAction" type="com.apache.struts.LoginAction" name="loginForm" input="/jsp/Login.jsp" scope="request">
<forward name="success" path="/jsp/Success.jsp"/>
<forward name="failure" path="/jsp/Login.jsp"/>
</action>
</action-mappings>
<!-- specify controller so that tests work with struts 1.3 -->
<controller processorClass="org.apache.struts.action.RequestProcessor" />
</struts-config>
LoginActionTest.java
package com.apache.struts;
import servletunit.struts.MockStrutsTestCase;
/**
*
* @author subbulakshmi_g
* @web http://sites.google.com/site/suseeganesan
* @email subbuseema@gmail.com / subbu_seema@yahoo.co.in
*
*/
public class LoginActionTest extends MockStrutsTestCase {
public LoginActionTest(String testName) {
super(testName);
}
public void setUp() throws Exception {
super.setUp();
setInitParameter("validating","false");
}
public void testSuccessfulLogin() {
addRequestParameter("username","struts");
addRequestParameter("password","apache");
setRequestPathInfo("/LoginAction");
actionPerform();
verifyForward("success");
verifyForwardPath("/jsp/Success.jsp");
assertEquals("struts",getSession().getAttribute("authentication"));
verifyNoActionErrors();
}
public void testFailedLogin() {
addRequestParameter("username","struts");
addRequestParameter("password","name");
setRequestPathInfo("/LoginAction");
actionPerform();
verifyForward("failure");
verifyForwardPath("/jsp/Login.jsp");
verifyInputForward();
verifyActionErrors(new String[] {"error.password.mismatch"});
assertNull(getSession().getAttribute("authentication"));
addRequestParameter("username","apache");
addRequestParameter("password","struts");
setRequestPathInfo("/LoginAction");
actionPerform();
verifyForward("failure");
verifyForwardPath("/jsp/Login.jsp");
verifyInputForward();
assertNull(getSession().getAttribute("authentication"));
addRequestParameter("username","");
addRequestParameter("password","");
setRequestPathInfo("/LoginAction");
actionPerform();
verifyForward("failure");
verifyForwardPath("/jsp/Login.jsp");
verifyInputForward();
}
public static void main(String[] args) {
junit.textui.TestRunner.run(LoginActionTest.class);
}
}
This is a simple sample to explain about strutstestcase/MockStrutsTestCase. We can see some other samples for how the MockStrutsTestCase will work for ActionForm when submitting files for uploading or to get object for getRealPath(“/”) as well as sample for CactusStrutsTestCase in my next tutorial. If you need more details visit the following sites.
References:
http://struts.apache.org/1.x/userGuide/introduction.html
http://j2ee.masslight.com/Chapter4.html
http://strutstestcase.sourceforge.net/
http://open.ncsu.edu/se/tutorials/junit/
http://www.laliluna.de/assets/tutorials/junit-testing-en.pdf