`
wwwlgy
  • 浏览: 8693 次
社区版块
存档分类
最新评论

编程小技巧共享(serverlet测试桩)

 
阅读更多

这个是我觉得写的比较好的一个工具。用他可以不用启动servlet容器直接对servlet进行测试。
总的来说,我是比较鄙视jsp的。这种混合型的语言无法测试(不要相信apache的仙人掌,骗人的,很不好用)。
所以在写web应用的时候,尽量将servlet分开,不用jsp就不用。一定要用,也是先请求到servlet,然后在servlet中forward到jsp上,让jsp处理尽量简单的逻辑。因为jsp真的无法测试。好了,分享一下这几个测试桩函数吧。

/*
* ServletProxy.java
*
* Created on 2007年7月7日, 上午8:46
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package wwwlgy.commspport.supportif.test;

import java.lang.reflect.*;
import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;
import java.util.*;

/**
*
* @author happy
*/
public class ServletRequestProxy implements InvocationHandler{

public ServletRequestProxy(){

}

public static HttpServletRequest createRequest(ServletRequestProxy p_proxy){
return (HttpServletRequest)Proxy.newProxyInstance(HttpServletRequest.class.getClassLoader(),new Class[]{HttpServletRequest.class},p_proxy);
}



private HashMap<String,String> parameterMap = new HashMap<String,String>();
private HashMap<String,Object> attributeMap = new HashMap<String,Object>();

private Object innerInvoker(Object proxy,Method method,Object[] args,Object moke)throws Throwable{
System.out.println("method:"+method);
System.out.println("method name:"+method.getName());
Method[] thisMethod = moke.getClass().getMethods();
for (Method m:thisMethod){
if(!m.getName().equals(method.getName())){
continue;
}
Class[] thisPc = m.getParameterTypes();
Class[] inputPc = method.getParameterTypes();
if(thisPc.length == inputPc.length){
for(int i=0;i<thisPc.length;i++){
if (!thisPc[i].equals(inputPc[i])){
return null;
}
}

return m.invoke(moke,args);
}
}
return null;
}
public Object invoke(Object proxy,Method method,Object[] args)throws Throwable{
return this.innerInvoker(proxy,method,args,this);
}

/**
*这是一个servlet的类,不直接使用,便于后面类继承使用
*/
public static class ServletInputStreamCreater extends ServletInputStream{
InputStream in;
public ServletInputStreamCreater(InputStream pin){
this.in = pin;
}
public int available()throws IOException{
return this.in.available();
}

public void close()throws IOException{
this.in.close();
}

public void mark(int readlimit){
this.in.mark(readlimit);
}

public void reset()throws IOException{
this.in.reset();
}

public boolean markSupported(){
return this.in.markSupported();
}

public int read() throws java.io.IOException{
return this.in.read();
}

public int read(byte[] b)throws IOException{
return this.in.read(b);
}
public int read(byte[] b,int off,int len)throws IOException{
return this.in.read(b,off,len);
}
public long skip(long n)throws IOException{
return this.in.skip(n);
}
}
public static class MyDispatcher implements RequestDispatcher{
private String Url;
private MyDispatcher(String pUrl){
this.Url = pUrl;
}
public void include(ServletRequest request,ServletResponse response){

}

public void forward(ServletRequest request,ServletResponse response){

}

//重载toString方法
public String toString(){
return this.Url;
}
}
//下面是这个类的要模拟的request对象的方法
public void setParameter(String pName,String pValue){
this.parameterMap.put(pName,pValue);
}

public HashMap<String, String> getParameterMap() {
return parameterMap;
}

public String getParameter(String pName){
return this.parameterMap.get(pName);
}

public void setAttribute(String pName ,Object pValue){
this.attributeMap.put(pName,pValue);
}

public Object getAttribute(String pName){

return this.attributeMap.get(pName);
}
public ArrayList<RequestDispatcher> myDispatcherList = new ArrayList<RequestDispatcher> ();
public RequestDispatcher getRequestDispatcher(String url){
RequestDispatcher result = new MyDispatcher(url);
myDispatcherList.add(result);
return result;
}

HttpSession mySession = null;
public HttpSession getSession(){
if (mySession == null){
mySession = ServletSessionProxy.createRequesst();
}
return mySession;
}

public HttpSession getSession(boolean flag){
return getSession();
}

public String getMethod(){
return "Post";
}

private HashMap<String,String[]> values = new HashMap<String,String[]>();
public void setParameterValues(String key,String[]values){
this.values.put(key,values);
}
public String[] getParameterValues(String key){
return this.values.get(key);
}

public static class MyEnumeration implements Enumeration{
Iterator it;
MyEnumeration(Iterator p_it){
it = p_it;
}
public boolean hasMoreElements(){
return it.hasNext();
}
public Object nextElement(){
return it.next();
}
}
public Enumeration getParameterNames(){
Iterator<String> it = this.parameterMap.keySet().iterator();
return new MyEnumeration(it);
}

private String remoteAddr;
public void setRemoteAddr(String ip){
this.remoteAddr = ip;
}
public String getRemoteAddr(){
return this.remoteAddr;
}

public static void main(String[]args)throws Exception{
try{
RequestDispatcher d;
viewAbstract(ServletInputStream.class);
viewConstructor(ServletInputStream.class);
ServletRequestProxy requestProxy = new ServletRequestProxy();
HttpServletRequest request = ServletRequestProxy.createRequest(requestProxy);

requestProxy.setParameter("aa","1111");
System.out.println(" request.getParameter :"+request.getParameter("aa"));

request.setAttribute("sdf","ddd");
System.out.println("request.getAttribute():"+request.getAttribute("sdf"));

RequestDispatcher dp= request.getRequestDispatcher("<<<dispatch>>>");
System.out.print("dispatcher :" + dp);

HttpSession session = request.getSession();
session.setAttribute("iiii","session test");

session = request.getSession(false);
System.out.println("session is :"+session.getAttribute("iiii"));
}catch (Exception e){
e.printStackTrace();
}
}


private static void viewAbstract(Class c){
Method[] ms = c.getMethods();
for (Method m:ms){
if (Modifier.isAbstract(m.getModifiers())){
System.out.println("--view Abstract"+c.getName()+" --:" + m);
}
}
}

private static void viewConstructor(Class c){
Constructor[] cns = c.getConstructors();
//System.out.println("cns length::"+ cns.length);
for (Constructor cn:cns){

System.out.println("--view Abstract"+c.getName()+" --:" + cn);

}
}
}


/*
* ServletSessionProxy.java
*
* Created on 2007年7月17日, 上午8:23
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package wwwlgy.commspport.supportif.test;
import java.lang.reflect.*;
import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;
import java.util.*;
/**
*
* @author happy
*/
public class ServletSessionProxy implements InvocationHandler {

/** Creates a new instance of ServletSessionProxy */
public ServletSessionProxy() {
}

public static HttpSession createRequesst(){
return createRequest(new ServletSessionProxy());
}
public static HttpSession createRequest(ServletSessionProxy p_proxy){
return (HttpSession)Proxy.newProxyInstance(HttpSession.class.getClassLoader(),new Class[]{HttpSession.class},p_proxy);
}

private Object innerInvoker(Object proxy,Method method,Object[] args,Object moke)throws Throwable{
System.out.println("method:"+method);
System.out.println("method name:"+method.getName());
Method[] thisMethod = moke.getClass().getMethods();
for (Method m:thisMethod){
if(!m.getName().equals(method.getName())){
continue;
}
Class[] thisPc = m.getParameterTypes();
Class[] inputPc = method.getParameterTypes();
if(thisPc.length == inputPc.length){
for(int i=0;i<thisPc.length;i++){
if (!thisPc[i].equals(inputPc[i])){
return null;
}
}

return m.invoke(moke,args);
}
}
return null;
}
public Object invoke(Object proxy,Method method,Object[] args)throws Throwable{
return this.innerInvoker(proxy,method,args,this);
}

//下面名模拟方法
private HashMap<String,Object> attr = new HashMap<String,Object>();
public void setAttribute(String pName,Object pObject){
this.attr.put(pName,pObject);
}
public Object getAttribute(String pName){
return this.attr.get(pName);
}
}


/*
* UploadServletRequestProxy.java
*
* Created on 2008年1月24日, 上午9:11
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package wwwlgy.commspport.supportif.test;
import java.util.*;

import java.lang.reflect.*;
import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;

/**
*
* @author happy
*/
/**
*
* @author happy
*/
public class UploadServletRequestProxy extends ServletRequestProxy{
private String boundary = "---------------------------7d73d8192026e";


private String contentType = "multipart/form-data; boundary="+boundary;
private String method = "post";

private HashMap<String,String>parameterMap = new HashMap<String,String>();

private HashMap<String,byte[]>fileMap = new HashMap<String,byte[]>();

private byte[]content = new byte[50000000];
private int contentLen;
private String defaultContentType = "text/plain";
private HashMap<String,String>contenttypeMap = new HashMap<String,String>();

private boolean finished = false;

/** Creates a new instance of UploadServletProxy */
public UploadServletRequestProxy() {
}

/**
*设置参数
*/
public void setParameter(String pName,String pValue){
if(finished){
throw new RuntimeException("finished setting");
}
this.parameterMap.put(pName,pValue);
}
/**
*设置文件,要求文件名和上面的参数名相同,而上面的值为文件名
*/
public void setFiles(String name,byte[]file){
if(finished){
throw new RuntimeException("finished setting");
}
this.fileMap.put(name,file);
}

/**
*设置文件的内容类型
*/
public void setFilesContentType(String name,String type){
if(finished){
throw new RuntimeException("finished setting");
}
this.contenttypeMap.put(name,type);
}

/**
*完成所有设置
*/
public void finished()throws Exception{
//处理普通参数
Set<String> nameSet = this.parameterMap.keySet();
String cd = "Content-Disposition: form-data; name=/"";
String finishedStr = "--"+boundary+"--/r/n";

this.contentLen = 0;
for(String name:nameSet){
byte[] file = this.fileMap.get(name);
String value = this.parameterMap.get(name);

StringBuilder sb = new StringBuilder();
sb.append("--").append(this.boundary).append("/r/n");
sb.append(cd).append(name).append("/"");
if (file == null){
//不是文件
sb.append("/r/n/r/n");
sb.append(value).append("/r/n");
} else{
//是文件
sb.append("; filename=/""+value+"/"").append("/r/n");
String type = this.contenttypeMap.get(name);
if (type == null){
type = this.defaultContentType;
}
sb.append("Content-Type: ").append(type).append("/r/n/r/n");
}

//将内容拷贝到数组中
byte[] tmpContent = sb.toString().getBytes();
System.arraycopy(tmpContent,0,this.content,this.contentLen,tmpContent.length);
this.contentLen+=tmpContent.length;

//如果是文件,将文件拷入到内容数组中
if (file != null){
tmpContent = file;
System.arraycopy(tmpContent,0,this.content,this.contentLen,tmpContent.length);
this.contentLen+=tmpContent.length;
this.content[this.contentLen++] = 13;
this.content[this.contentLen++] = 10;
}
}

byte[] tmpContent = finishedStr.getBytes();
System.arraycopy(tmpContent,0,this.content,this.contentLen,tmpContent.length);
this.contentLen+=tmpContent.length;

//System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/n"+new String(this.content,0,this.contentLen));
this.finished = true;
}

public String getMethod(){
return this.method;
}

public String getContentType(){
return this.contentType;
}

public int getContentLength(){
return this.contentLen;
}

public ServletInputStream getInputStream() throws java.io.IOException{
ByteArrayInputStream in = new ByteArrayInputStream(this.content,0,this.contentLen);
return new ServletRequestProxy.ServletInputStreamCreater(in);
}
}

最后一个函数是模拟一些文件上传的桩函数,作测试的时候很好用的。我具个例子吧:

requestHandle = new ServletRequestProxy();
request = ServletRequestProxy.createRequest(requestHandle);

int pageIdx = pdate.locationPage_idx[0];//使用默认页面测试
int locationIdx = pdate.location_idx[0];//使用第一个locatioin
int pageType = pdate.locationPage_pagetype[0];
//设置参数
requestHandle.setParameter(PageOperConst.WEBPARAMETER_NAME_PAGEINDEX,String.valueOf(pageIdx));
requestHandle.setParameter(PageOperConst.WEBPARAMETER_NAME_PAGETYPE,String.valueOf(pageType));
requestHandle.setParameter(PageOperConst.WEBPARAMETER_NAME_LOCATIONINDEX,String.valueOf(locationIdx));


LocationDel instance = new LocationDel();//LocationDel就是一个servlet

instance.processRequest(request, response);

然后检查:
//检查返回的结果信息是否正确
assertEquals("操作正确情况下,返回结果信息应该正确",ResultInfo.SUCCESSFUL,request.getAttribute(WebOperConst.REQUESTATTRIBUTE_NAEM_RESULTINFO));
//判断转向
assertEquals("成功情况下的转向",WebOperConst.DEFAULTSUCCESSPAGE,requestHandle.myDispatcherList.get(0).toString());

版权声明:本文为博主原创文章,未经博主允许不得转载。

分享到:
评论

相关推荐

    java serverlet 小实例

    通过实践这些Java Servlet小实例,可以更好地理解和掌握Web开发中的服务器端编程。 总之,Java Servlet是构建动态Web应用的关键技术,它允许开发者使用Java语言处理HTTP请求,实现与客户端的交互。通过学习和实践这...

    serverlet相关基础题

    - **Cookie**:存储在客户端浏览器上的小文本文件,用于跟踪用户信息。 #### 8. 设置和获取请求属性 - **设置属性**:使用`setAttribute(String name, Object value)`方法设置名为`name`的属性值。 - **获取属性**...

    jsp&serverlet api开发文档

    jsp&serverlet api开发文档

    jsp+serverlet+oracle

    《基于JSP+Servlet+Oracle的网上订餐系统解析》 ...总的来说,"jsp+serverlet+oracle"的组合提供了一个理想的实践平台,让初学者在实践中学习,在学习中实践,从而更好地理解和掌握Web开发的核心技术。

    Java_tomcat_和serverlet的使用

    Java_tomcat_和serverlet的使用

    Ajax与Serverlet原理及应用.zip

    你可以从“Ajax与Serverlet原理及应用”这个文件开始,逐步学习这两个技术的细节,包括它们如何协同工作以创建高效的Web应用程序。 总的来说,Ajax和Servlet的结合使用能够提供高性能、高度交互的Web界面,极大地...

    serverlet4Json

    serverlet Json commons-beanutils-1.7.0.jar commons-collections-3.2 .jar commons-lang-2.4.jar commons-logging.jar ezmorph-1.0.6.jar json-lib-2.2.3-jdk15.jar xmlns=...

    java serverlet 实例

    Java Servlet是一种Java编程技术,用于扩展Web服务器的功能,使得服务器能够处理HTTP协议,进而构建动态、交互式的Web应用。Servlet是Java EE(企业版)的一部分,它为开发人员提供了处理客户端请求并返回响应的能力...

    基于javaweb+jsp+serverlet

    **基于JavaWeb+jsp+Servlet的图书管理系统** JavaWeb技术是构建互联网应用程序的强大工具,它结合了Java语言...在实际开发过程中,还需要考虑用户体验、性能优化、测试策略等多个方面,以确保系统的高效、稳定和易用。

    javaWeb系列 serverlet最简单登陆代码

    Servlet是Java编程语言中的一个接口,它为Java应用程序提供了一个标准的方法来响应HTTP请求,是Java Web开发的核心部分。 首先,我们需要创建一个Servlet类,继承自HttpServlet。这个类会处理HTTP请求并生成HTTP...

    JSP serverlet 增删查改

    JSP serverlet 增删查改JSP serverlet 增删查改JSP serverlet 增删查改JSP serverlet 增删查改JSP serverlet 增删查改JSP serverlet 增删查改JSP serverlet 增删查改JSP serverlet 增删查改JSP serverlet 增删查改

    JSP基于serverlet网上书店系统

    在这个系统中,JavaBean可能包含了书籍信息、用户信息等实体类,方便在Servlet和JSP之间共享数据。 4. **MySQL**:MySQL是一款开源的关系型数据库管理系统,用于存储和管理网上书店的各类数据,如书籍信息、订单...

    jsp第2集视频关于serverlet

    这是我接着上次传的jsp视频,都是来子培训班的东西; 先传2集;有人下载了我传剩下的要不也没什么用

    javabean+mysql+serverlet 学生成绩管理系统

    【标题】"javabean+mysql+serverlet 学生成绩管理系统"是一个基于J2EE技术栈构建的应用,主要用于管理教育机构的学生成绩。在这样的系统中,JavaBean是核心组件,它作为数据封装的载体,实现了业务逻辑;MySQL是常用...

    JSP和Serverlet之间的传值方法

    ### JSP与Servlet之间的传值方法详解 #### 一、引言 在Web开发中,JSP(JavaServer Pages)和Servlet是两个重要的技术组成部分,它们通常被用来处理客户端请求并生成动态网页内容。为了实现功能更为复杂的应用,...

    JSP +SERVERLET+JAVABEAN

    **Servlet** 是Java语言编写的小程序,运行在服务器端,用于处理和响应来自客户端(如浏览器)的请求。Servlet生命周期包括加载、初始化、服务和销毁四个阶段。Servlet与JSP的关系是,JSP最终会被编译为Servlet执行...

    在线考试系统jsp+serverlet

    综上所述,"在线考试系统jsp+serverlet"是一个综合运用Java Web技术构建的教育信息化平台,它通过jsp提供友好的用户界面,借助servlet处理复杂的业务逻辑,从而实现教师、学生和管理员的各类功能需求。

    Flex在myeclipse下如何配置以及用serverlet的交互

    Flex是一种开源的、基于ActionScript的开放Web标准,主要用于创建富互联网应用程序(RIA)。它能够构建功能丰富的、交互性强的用户界面,常用于桌面和移动应用程序。MyEclipse是一款强大的集成开发环境,支持多种...

    jsp/serverlet论坛代码

    【标题】"jsp/serverlet论坛代码"所涉及的知识点主要集中在Java服务器页面(JSP)和Servlet技术上,这是Web应用程序开发中常见的两种技术。JSP是Java平台上的动态网页技术,而Servlet则是Java编程语言中用于扩展Web...

Global site tag (gtag.js) - Google Analytics