servletにユニットテストのまとめを書きます.


回転:
http://blog.csdn.net/cz_hyf/archive/2007/02/10/157211 aspx
servletのテストは一般的にコンテナのサポートが必要です.通常のjava類のjunnitテストのように簡単ではありません.次にHello Worldコードのテストを通して、いくつかのservletテスト方法を説明します.テストされたハロルド類のコードは以下の通りです.

/**
 *     servlet
 */
import java.io.IOException; 
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class HelloWorld extends HttpServlet{
 
 public void saveToSession(HttpServletRequest request) {
         request.getSession().setAttribute("testAttribute",request.getParameter("testparam"));
}
 
 public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException{
         String username=request.getParameter("username");
         response.getWriter().write(username+":Hello World!");        
 }
 
 public boolean authenticate(){         
        return true; 
 }

}
ハロルドを例にとって、Servletの様々なテスト方法をまとめました.
一.Http Unitを使ってテストする

import com.meterware.httpunit.GetMethodWebRequest;
import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;
import com.meterware.servletunit.InvocationContext;
import com.meterware.servletunit.ServletRunner;
import com.meterware.servletunit.ServletUnitClient;
import junit.framework.Assert;
import junit.framework.TestCase;
 
public class HttpUnitTestHelloWorld extends TestCase {
 
 protected void setUp() throws Exception {
  super.setUp();
 }
 
 protected void tearDown() throws Exception {
  super.tearDown();
 }
 
 public void testHelloWorld() {

		try {

			//   Servlet     
			ServletRunner sr = new ServletRunner();

			//       Servlet
			sr.registerServlet("HelloWorld", HelloWorld.class.getName());

			//     Servlet    
			ServletUnitClient sc = sr.newClient();

			//     
			WebRequest request = new GetMethodWebRequest(
					"http://localhost/HelloWorld");
			request.setParameter("username", "testuser");

			InvocationContext ic = sc.newInvocation(request);

			HelloWorld is = (HelloWorld) ic.getServlet();

			//   servlet     
			Assert.assertTrue(is.authenticate());

			//           
			WebResponse response = sc.getResponse(request);

			//   
			Assert.assertTrue(response.getText().equals("testuser:Hello World!"));

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
 
}
上記の例はjunnitのテスト例であり、httpunitシミュレーションを使用したservlet環境では、上述の方法を用いてservletをテストすると、コンテナから離れて、このテストをantまたはmavenスクリプトに書き込みやすくなり、テストを行わせます.
httputnit URL:
http://httpunit.sourceforge.net/
この方法を使ってテストする弱点は、requestのset Charter Enccoding方法を使うと、テストにいくつかの問題が発生します.また、httputnitはservlet行為をテストする時、完全なシミュレーションブラウザを採用しています.テストが難しい場合があります.
二はcactusを使ってテストします.

/**
 * cactus  servlet   
 *     tomcat   
 */
import junit.framework.Test;
import junit.framework.TestSuite;
import org.apache.cactus.ServletTestCase; 
import org.apache.cactus.WebRequest;
import org.apache.cactus.WebResponse;
public class CactusHelloWorld extends ServletTestCase{
  
     HelloWorld servlet;
     public CactusHelloWorld(String theName) {
         super(theName);
     }
 
     protected void setUp() throws Exception {
         super.setUp();
         servlet = new HelloWorld();
     }
 
     protected void tearDown() throws Exception {
         super.tearDown();
     }
 
     /**
      *             
     * @param webrequest
      */
 
     public void beginSaveToSessionOK(WebRequest request) {
         request.addParameter("testparam", "it works!");
     }
     
     /**
      *             
      * 
      * @param webrequest
      */
 
     public void beginDoGet(WebRequest request) {
         request.addParameter("username", "testuser");
     }
 
     /**
      *   servlet     
      *  
      */

     public void testSaveToSessionOK() {
         servlet.saveToSession(request);
         assertEquals("it works!", session.getAttribute("testAttribute"));
     }
 
     public void testDoGet() {
         try {
             servlet.doGet(request, response);
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
 
     /**
      *               ,        reponse end***,      cactus
      *  WebResponse     httpunit  ,    httpunit response
      * 
      * @param response
      */

     public void endDoGet(WebResponse response) {
         String content;         
         content = response.getText();
         assertEquals("testuser:Hello World!", content);
     }
}
 
cactusは多様な柔軟なテスト機能を備えています.例えば、doGet方法をテストするなら、begin DGet(アナログテストパラメータ設定)、DoGet(実行テスト)、endDoGet(状態結果検証)に分けて、httpunitよりも書き込みテストが容易で、テストservletはより専門的で、流れがより明確です.しかし、cactusは容器サポートが必要で、テストは自動的に行われません.しかし、組み込み容器を使うと、自動的にテストができます.
cactusはservletとjspのテストフレームです.
http://jakarta.apache.org/cactus/getting_started.
三Jettyを組込み容器として使用してservletをテストします.

/**
 *        jetty     ,jetty  stubs     
 */
package com.easyjf.testexample;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.bio.SocketConnector;
import org.mortbay.jetty.servlet.ServletHandler; 
import com.meterware.httpunit.WebClient;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebResponse; 
import junit.framework.Assert;
import junit.framework.TestCase;
 
public class JettySampleTest extends TestCase {
 
 Server server;
 protected void setUp() throws Exception {
      //              ,     servlet     
      super.setUp();
      server = new Server();
      Connector connector=new SocketConnector();
      connector.setPort(80);
      server.setConnectors(new Connector[]{connector});
      ServletHandler handler=new ServletHandler();
      server.setHandler(handler);
      handler.addServletWithMapping("HelloWorld", "/");
      server.start();
 }
 
 protected void tearDown() throws Exception {
  super.tearDown();
  server.stop();
 }
 
 public void testHellWorld() {
  try {
   WebConversation wc = new WebConversation();
   WebResponse web = wc.getResponse("http://127.0.0.1/HelloWorld");
   String result=web.getText();
   Assert.assertEquals(result,"it works!");
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}
 
キティちゃんはservletの容器として働くことができます.便利なのは、キティさんは組み込みサービスをサポートしています.つまりコードで起動することができます.自動テストの例を書くには便利です.httpunnitまたはcactusと組み合わせてservletテストを行うことができます.
キティちゃんのホームページ:
http://docs.codehaus.org/display/JETTY/Embedding+Jetty
四mockオブジェクトを使用し、ここでeasymockを使用する.
 
import java.io.PrintWriter;
import java.io.Writer;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; 
import junit.framework.Assert;
import junit.framework.TestCase;
import static org.easymock.EasyMock.*;
public class MockTestServlet extends TestCase {
 
    public void testService() throws Exception {

        System.out.println("service");

        HttpServletRequest request = createMock(HttpServletRequest.class);

        HttpServletResponse response = createMock(HttpServletResponse.class);

        //Creating the ServletConfig mock here

        ServletConfig servletConfig = createMock(ServletConfig.class);

        //Creating the ServletContext mock here

        ServletContext servletContext = createMock(ServletContext.class);
        
        //Create the target object  
      
        HelloWorld4 instance = new HelloWorld();

        //   servlet,       ,    servletConfig       ,        

        instance.init(servletConfig);
 
        //                 ,            servletConfig getServletContext  ,      
 
        //servletContext,  servletConfig mock   ,        。

        expect(servletConfig.getServletContext()).andReturn(servletContext).anyTimes();

        expect(request.getParameter("username")).andReturn("testuser");

        PrintWriter pw=new PrintWriter(System.out,true);

        expect(response.getWriter()).andReturn(pw).anyTimes();
        
        //      ,     ,     easymock    ,     easymock       
        replay(request);
        replay(response);
        replay(servletConfig);
        replay(servletContext);
 
        instance.doGet(request, response);

        pw.flush();        
 
        //        ,    ,   pw   testuser.
        verify(request);
        verify(response);
        verify(servletConfig);
        verify(servletContext);
   }
}
 
mockテストは行動を重視しています.mockオブジェクトは全部シミュレーションの対象です.方法は通常直接にリターン値を与えます.具体的な対象論理がなく、mockオブジェクトはテストを助けるためのクラスです.例えばservletの内部行為をテストしたり、容器がほしくないなどの環境をテストするなら、mockテストを採用することができます.
easymockはmockテストの枠組みである.
http://www.easymock.org/