JUnit is the current most popular test framework that allows developers to prepare test units, which can develop them "rest assured". But now a lot of applications are based on J2EE, and the code is running in the container of the server side, which makes the test some trouble. For ordinary JSPs, servlets are not so convenient with JUnit. For EJB, especially version 2.0, many interfaces are local interface, there is no way to distribute. So how do we test these code? Apache provides us with a powerful tool Cactus! It is a simple, easy-to-use server-side test framework that makes developers' programs that are relaxed to test server-side programs, they will say: "Oh, it is so simple". Cactus is an extension of Junit, but it is different from JUnit. CACTUS test is divided into three different test categories, JSPTestCase, ServletTestcase, FilterTestCase, not like Junit, a TestCase. CACTUS's test code has two parts of the server side and the client, and they work together. Then why don't we use JUnit to do test? There are several reasons:
Local Interface in EJB2.0, is not allowed to call remote calls. With JUnit is not tested, and CACTUS's Redirector is located on the server, and can run in a container with the EJB, which allows it to access local interface directly. General EJB or Servlet, JSP is running on the server. If you use JUnit test, your test is on the client, which makes the running environment and test environment in different system environments, this sometimes different tests result. In an EJB application, there are some front-end applications to access EJBs, such as: JSP, Servlet, JavaBean. This means that you need a test framework to test the components of these front ends. CACTUS provides test methods for all of these components. Oh, great. Cactus and Ant are well combined, which can easily complete the automation test, which reduces a lot of workload. Of course, JUnit also provides such support.
The front is a rough introduction to CACTUS, followed by using an actual example to use this powerful test framework. First we need an object that is tested, here we choose EJB2.0 CMP. We do a simple user management. Take some major code to conduct some analyzes.
Userhome.java
Package UserSystem;
Import javax.ejb. *;
Import java.util. *;
Public interface userhome extends javax.ejb.ejblocalhome {
Public User Create (String Name, String Password) THROWS CREATEXCEPTION;
Public Collection Findall () THROWS FINDEREXCEPTION;
Public User FindByPrimaryKey (String Name) Throws FinderException;
}
User.java
Package UserSystem;
Import javax.ejb. *;
Import java.util. *;
Public interface user extends javax.ejb.ejblocalObject {
Public string getname ();
Public void setPassword (String Password); public string getpassword ();
Public void setuserinfo (userInfo userinfo);
Public UserInfo getUserInfo ();
Public void setname (String name);
}
Userinfohome.java
Package UserSystem;
Import javax.ejb. *;
Import java.util. *;
Public interface userinfohome extends javax.ejb.ejblocalhome {
Public UserInfo Create (String Name, String Email, String Address, String Tel) Throws
CreateException;
Public UserInfo FindByPrimaryKey (String Name) throws FinderException;
}
There are two Entity beans to create user information. The relationship between them is described in the XML deployment description file that they are 1-to-1 relationship.
Usermanagerlocal.java
Package UserSystem;
Import javax.ejb. *;
Import java.util. *;
Public interface UserManagerLocal Extends Javax.ejb.eblocalobject {
Public void adduser (String Name, String Password, String Email, String Address, String Tel);
Public Collection FindAll ();
Public void deLall ();
Public void DelbyName (String Name);
Public user FindByname (String Name);
}
Usermanagerbean.java
Package UserSystem;
Import javax.ejb. *;
Import javax.rmi.portableremoteObject;
Import javax.naming. *;
Import java.util. *;
Public Class UserManagerBean Implements SessionBean {
SessionContext sessionContext;
Public void ejbcreate () throws createException {
/ ** @ Todo Complete this method * /
}
Public void ejbremove () {
/ ** @ Todo Complete this method * /
}
Public void ejbactivate () {
/ ** @ Todo Complete this method * /
}
Public void ejbpassivate () {
/ ** @ Todo Complete this method * /
}
Public void setsessionContext (sessioncontext sessioncontext) {
This.SessionContext = sessionContext;
}
/ **
* Add user
* @Param Name user name
* @Param Password password
* @Param Email Email
* @Param Address address
* @Param Tel Phone
* /
Public void adduser (String Name, String Password, String Email, String Address, String Tel) {TRY {
UserHome UserHome = getUserHome ();
User User = UserHome.create (Name, Password); // CREATE User Entity
Userinfohome userinfohome = getUserInfoHome ();
Userinfo userinfo = userinfohome.create (Name, email, address, tel); // Create UserInfo
Entity
User.setUserInfo (UserInfo);
} catch (exception e) {
Throw new javax.ejb.ejbexception (e.tostring ());
}
}
/ **
* Return to the UserHome interface
* @Return Userhome
* /
Private usrhome getuserhome () {
Try {
Javax.naming.initialcontext ctx = new javax.naming.initialContext ();
Object ref = ctx.lookup ("user");
// Cast to Home Interface
UserHome UserHome = (UserHome) PortableRemoteObject.Narrow (Ref, UserHome.Class);
Return UserHome;
}
Catch (classcastexception ex) {
EX.PrintStackTrace ();
Return NULL;
} catch (namingexception ex) {
EX.PrintStackTrace ();
Return NULL;
}
}
/ **
* Return to the UserInfoHome interface
* @Return
* /
Private userinfohome getuserinfohome () {
Try {
Javax.naming.initialcontext ctx = new javax.naming.initialContext ();
Object ref = ctx.lookup ("UserInfo");
// Cast to Home Interface
Userinfohome userinfohome = (userinfohome) PortableRemoteObject.narrow (Ref,
Userinfohome.class;
Return UserInfoHome;
}
Catch (classcastexception ex) {
Throw new ejbexception ();
} catch (namingexception ex) {
Throw new ejbexception (ex. TString ());
}
}
/ **
* Return to all user records
* @return C
* @Throws javax.ejb.findeRexception
* /
Public java.util.collection findall () {
Collection C = NULL;
Try {
Userhome uh = this.getuserHome ();
C = uh.findall ();
}
Catch (FINDEREXCEPTION EX) {
Throw new javax.ejb.ejbexception ();
}
Return C;
}
/ **
* Delete all records
* /
Public void deLall () {
Try {
UserHome u = getUserHome ();
Java.util.collection c = u.findall ();
Java.util.iterator i = c.iterator ();
While (I.hasNext ()) {
U.Remove ((user) i.next ()). getName ());
}
}
Catch (Exception EX) {
Throw new ejbexception (ex. TString ());
}
}
/ **
* Delete record according to username
* @Param Name
* /
Public void delbyname (String name) {
Try {
User User = FindByname (Name);
Userhome uh = getUserHome ();
UH.Remove (user.getname ());
}
Catch (Exception EX) {
Throw new javax.ejb.ejbexception (ex.totring ());
}
}
/ **
* Find user records via username
* @Param Name
* @Return
* /
Public user findbyname (string name) {
Try {
Userhome uh = this.getuserHome ();
User user = (user) uh.findbyprimarykey (name);
Userhome u = this.getuserHome ();
User uu = u.findbyprimaryKey (Name);
Return User;
}
Catch (FINDEREXCEPTION EX) {
Throw new ejbexception (ex. TString ());
}
}
}
UserManagerBean is a session bean, which is mainly administrative, and client communication, actually the session facade mode. There is a comment in the code, which is not described here.
EJB-JAR.XML Deployment Document Description
XML Version = "1.0" encoding = "UTF-8"?>
"http://java.sun.com/dtd/ejb-jar_2_0.dtd">
ejb-local-ref>
ejb-local-ref>
session>
cmp-field>
cmp-field>
query-method>
query>
Entity>
cmp-field>
cmp-field>
cmp-field>
cmp-field>
Entity>
enterprise-beans>
rateship-role-source>
CMR-Field>
EJB-RELATIONSHIP-ROLE>
rateship-role-source>
CMR-Field>
EJB-RELATIONSHIP-ROLE>
EJB-RELATION>
rateships>
Method>
container-transaction>
Method>
container-transaction>
Method>
container-transaction>
askSEMBLY-Descriptor>
ejb-jar>
Next is the client accessing the EJB, we used a servlet.
Manaservlet.java
Package usersystem.servlet;
Import javax.servlet. *;
Import javax.servlet.http. *;
Import java.io. *;
Import java.util. *;
Import usersystem. *;
Import javax.naming. *;
Import javax.ejb. *;
Import javax.ejb. *;
Import javax.ejb. *;
/ **
*
Title: p>
*
description: p>
*
Copyright: CopyRight (C) 2002 P>
*
company: p>
* @Author unascribed
* @version 1.0
* /
Public Class Manaservlet Extends httpservlet {
Static Final Private String content_type = "text / html; charSet = GBK";
Private usermanagerlocalhome h = null;
Private usermanagerlocal uml = null;
Public void init () throws servletexception {
Try {
H = gethome ();
UML = H.CREATE ();
}
CATCH (CreateException EX) {
EX.PrintStackTrace ();
}
}
Public void doget (httpservletRequest Request, HttpservletResponse Response) THROWS
ServletException, IOException {
}
Public Void Dopost (httpservletRequest Request, HttpservletResponse Response) THROWS
ServletException, IOException {
}
Public Void AddUser (httpservletRequest Request, httpservletResponse response) throws
Javax.ejb.ejbexception {
String name = Request.getParameter ("name");
String Tel = Request.getParameter ("tel");
String address = request.getParameter ("address");
String email = Request.getParameter ("email");
String Pass = Request.getParameter ("pass");
Uml.adduser (Name, Pass, Email, Address, Tel);
}
Public user findbyname (string name) throws javax.ejb.ejbexception {
User u = NULL;
u = uml.findbyname (name);
Return U;
}
Public Java.util.ITerator Findall () throws javax.ejb.ejbexception {
Java.util.collection c = uml.findall ();
Return c.iterator ();
}
Public void deLall () throws javax.ejb.ejbexception {
Uml.deLall ();
}
Public void deluser (String name) throws javax.ejb.ejbexception {
Uml.delbyname (name);
}
Public userManagerlocalhome gethome () {
UserManagerLocalhome Home = NULL;
Try {
Javax.naming.initialcontext ctx = new javax.naming.initialContext ();
Home = (UserManagerLocalHome) CTX.lookup ("UserManagerLocal");
}
Catch (Namingexception EX) {
EX.PrintStackTrace ();
Return NULL;
}
Return home;
}
Public void destroy () {
}
}
This servlet does not implement any ways in doget, Dopost, this does not affect us test, we want to test these public method. Our test code is as follows:
Package UserSystem.test;
/ **
*
Title: p>
*
description: p>
*
Copyright: CopyRight (C) 2002 P>
*
company: p>
* @Author unascribed
* @version 1.0
* /
Import usersystem.servlet. *;
Import java.io.ioException;
Import java.net.urdecoder;
Import java.util.hashtable;
Import junit.framework.test;
Import junit.framework.testsuite;
Import org.apache.cactus.cookie;
Import org.apache.cactus.servlettestcase;
Import org.apache.cactus.WebRequest;
Import org.apache.cactus.WebResponse;
Import javax.ejb. *;
Import javax.servlet. *;
Import usersystem. *;
Public class manaservlettest extends servlettestcase {
Manaservlet servlet = new manaset ();
Public Manaservlettest (String thename) {
Super (thename);
}
Public void setup () {
Try {
servlet.init ();
}
Catch (servletexception ex) {
EX.PrintStackTrace ();
THIS.FAIL ();
}
}
Public void teardown () {
}
Public void beginadduser (WebRequest therequest)
{
Therequest.addParameter ("Name", "NameValue");
Therequest.addparameter ("Pass", "PassValue");
Therequest.addparameter ("Tel", "Telvalue");
Therequest.addparameter ("Address", "AddressValue");
Therequest.addparameter ("email", "emailvalue";
}
Public void testadduser () throws javax.ejb.ejbexception {
servlet.adduser (Request, Response);
}
Public void testfindall () {
Java.util.ITerator i = servlet.findall ();
// assertequals (null, i);
Boolean OK = FALSE;
While (I.hasNext ()) {
IF ((user)). getName (). Equals ("namevalue") {ok = true;
}
}
THIS.ASSERTTRUE (OK);
}
Public void testfindbyName () throws javax.ejb.ejbexception {
User u = servlet.findbyName ("NameValue");
Userinfo ui = u.getuserinfo ();
THIS.ASSERTEQUALS ("email", ui.getemail ());
THIS.ASSERTEQUALS ("tel", ui.gettel ());
THIS.ASSERTEQUALS ("NameValue", u.getname ());
THIS.ASSERTEQUALS ("PassValue", u.getPassword ());
}
Public void testdel () throws javax.ejb.ejbexception {
Servlet.deluser ("NameValue8");
}
Public void testdeLall () THROWS JAVAX.EJB.EJBEXCEPTION {
servlet.deLall ();
}
Public static void main (string [] THEARGS)
{
JUnit.textui.teStrunner.main (new string "
Manaservlettest.class.getname ()});
}
Public Static Test Suite ()
{
Return New TestSuite (ManaseVlettest.class);
}
}
Public Class Manasettest Extends ServletTestCase We want to test a servlet, so we inherit servlettestcase, if you test JSP, inherit JsptestCase.
Public Manaservlettest (String thename) {
Super (thename);
}
And JUnit, servletTestCase does not allow the use of the default constructor, so you must use a constructor with parameters and call the constructor of the parent class.
Public void setup () {
Try {
servlet.init ();
}
Catch (servletexception ex) {
EX.PrintStackTrace ();
THIS.FAIL ();
}
}
Public void teardown () {
}
Setup is the way to be called first in test class, where some data initialization can be performed here. Here we call servlet.init ().
The init () method of the explicit call servlet is required when the test class is run. Because CACTUS is instantified a Ser Vlet when testing servlet, Inti (), and servlet Enginer will automatically call the servlet's init () method when calling. TEARDOWN Method is running when the test is completed, and some necessary data processing, such as deleting some test data, etc. We have not done anything.
Public void beginadduser (WebRequest therequest)
{
Therequest.addParameter ("Name", "NameValue");
Therequest.addParameter ("Pass", "PassValue"); Therequest.addParameter ("Tel", "Telvalue");
Therequest.addparameter ("Address", "AddressValue");
Therequest.addparameter ("email", "emailvalue";
}
Public void testadduser () throws javax.ejb.ejbexception {
servlet.adduser (Request, Response);
}
In CACTUS, you need to use TestXxx to name your method so that Cactus will automatically call this method for testing. Beingxxx is called before the Test method is called, that is, running before a functional test. Here we now add some necessary parameters to Beginadduser. WebRequest is a class provided by CACTUS, which allows you to set some http parameters, if you use TheRequest.addParameter ("Name", "NameValue"), then you can use Request.GetParameter ("Name") in servlets. Take the value of Name. Of course, you can also set the cookie, http head parameters. In a TestAdduser () method, we test the Adduser method. If there is an abnormality, EJBEXCEPTION will produce a test failure.
Public void testfindbyName () throws javax.ejb.ejbexception {
User u = servlet.findbyName ("NameValue");
Userinfo ui = u.getuserinfo ();
THIS.ASSERTEQUALS ("email", ui.getemail ());
THIS.ASSERTEQUALS ("tel", ui.gettel ());
THIS.ASSERTEQUALS ("NameValue", u.getname ());
THIS.ASSERTEQUALS ("PassValue", u.getPassword ());
}
This test is to test the user according to the username, then you can use the Assertequals method to test whether the returned value is correct.
Public static void main (string [] THEARGS)
{
JUnit.textui.teStrunner.main (new string "
Manaservlettest.class.getname ()});
}
Here we use TextUi to run our test class, provide text's test information, and a Swing test method, a total of one interface, but there is nothing too much.
Here we introduce all the main methods. Finally, we talk about how to run this test.
First download CACTUS. Add the jar file in the lib / down to the LIB of the Web App. And in the client's classpath, this is the most insurance, although not all JARs are used. Set your CACTUS. Find the CACTUS.Properties file and add it to the client's classpath. Modify the CACTUS.PROPERTIES file, change http: // localhost: 8080 / test to your corresponding setting, Test is your name of your web application. Other settings can be unchanged. Modify the configuration of the server-side web application, add: XML Version = "1.0" eNCoding = "ISO-8859-1">
filter>
filter-mapping>
servlet>
servlet>
servlet-maping>
servlet-maping>
Compile EJB and Servlet, packed the JAR of the EJB file, package the WAR file of the servlet into an EAR file. Publish your EAR file to Web Application. Run Local Test File Manaservlettest.class
Haha ~~, finally completed all the work, we can look at the results, "Oh, no", there is an error, that is, your program has a problem, take a closer look, test is not lie of:) . The above code runs successfully on Win2000 JBoss3.0 MySQL MAX 3.24 CACTUS1.3.