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

编程小技巧共享(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());

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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics