锁定老帖子 主题:struts和webwork双体验
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2005-01-18
linux_china 写道 gigix 写道 没关系,你说说看你怎么测Struts action吧。
使用StrutsTestCase进行Struts的Action测试非常简单,当然也是支持自动测试的,我现在就使用这个做测试,修改一下可以整合Spring。 非常赞同设计也必须考虑测试的问题。 同样的,这个也需要借助第三方工具,所以复杂度会更高些。当然如果有其他因素考虑,是可取的。如果没有其他因素,我会建议用webwork,哪怕是需要多一些学习也值得。我现在的习惯不是“设计必须考虑测试”,而是没有测试就没办法设计和编码。 |
|
返回顶楼 | |
发表时间:2005-01-18
gigix 写道 linux_china 写道 gigix 写道 没关系,你说说看你怎么测Struts action吧。
使用StrutsTestCase进行Struts的Action测试非常简单,当然也是支持自动测试的,我现在就使用这个做测试,修改一下可以整合Spring。 非常赞同设计也必须考虑测试的问题。 同样的,这个也需要借助第三方工具,所以复杂度会更高些。当然如果有其他因素考虑,是可取的。如果没有其他因素,我会建议用webwork,哪怕是需要多一些学习也值得。我现在的习惯不是“设计必须考虑测试”,而是没有测试就没办法设计和编码。 struts没有想象的那么难测吧,使用StrutsTestCase已经很简单了。一个action又不会有很复杂的逻辑在里边,也就是测测forword对不对,验证一下session,request而已。 |
|
返回顶楼 | |
发表时间:2005-01-18
据说webwork是针对struts的缺点诞生的。
webwork的优点,不必多讲了,楼上的几位和opensymphony上都告诉了大家。对比的表也有。可以自己看看先。 我就拿自己的亲身体会说一下: 1、过去使用struts,苦于没有办法做unit test,很头疼;现在我再开发的时候,做Action类的时候,完全摆脱页面,我就可以测试Action执行是否畅通了。 这里有人说:struts有unit test工具,这只不过是一个弥补手段。struts的Action需要ServletRequest,ServletResponse作为参数,这就宣告了struts的Action和web container是紧耦合的。但是webwork的Action在xwork(xwork是个典型的MVC command模式,适用于任何客户端)当中,摆脱了对web容器的依赖。struts在Action的设计上与webwork是有差距的 2、struts的form bean非常让我厌烦,每次还要和Action一起定义一个form bean;用webwork,我直接使用Domaim Model做form bean,不需要任何设置。 3、struts的集中控制:类似于ServletFileter的功能的东东,没有办法在Action之后做一些自动化的事情。比如ThreadLocal中关闭HibernateSession;我用webwork的interceptor呢,可以在Action执行之前,执行之后,自动执行拦截操作,而且这些拦截操作可以对Action进行随意组合。很爽! ....... 呵呵,我是一个webwork的支持者。 |
|
返回顶楼 | |
发表时间:2005-01-18
gigix 写道 同样的,这个也需要借助第三方工具,所以复杂度会更高些。 StrutsTestCase只是JUnit的扩展包,不是第三方工具,不会复杂啊,除非不想用JUnit啦,不知道gigix是否使用过StrutsTestCase,如果WebWork的Action中确实包含了Web容器相关的代码,不知道此时的Action怎么测试? 我阅读过13本关于Struts的书籍,所以给Struts一个正面的解释。WebWork2设计的确实不错,IoC和interceptor是两个很好的功能,但是Struts也可以引入这种interceptor机制,如SAIF,同样也可以实现WebWork2的Interceptor和IoC功能,只不过大家想不想去做。 我对这两种框架以及Spring的MVC都没有明显的偏向,没有最好的框架,只有最适合的场合。 |
|
返回顶楼 | |
发表时间:2005-01-21
gigix 写道 flyfish 写道 gigix 写道 我最看重的是:Struts的接口到处都是Http....和Servlet...,你怎么测试它?如果不能测试它,你怎么敢在里面放更多的业务逻辑?WebWork的可测试性,不是Struts能比的。
虽然我也不用struts,但是我对于这样的说法实在难以认同!你写个测试用例,ant一下,那就是测试了??能通过这样的东西测试出什么来?测试用例是死的,但是人是活的。 没关系,你说说看你怎么测Struts action吧。 我想,你一直强调HttpServletRequest等接口很难测试的理由是需要Web容器。为什么Web容器能够测试呢,理由很简单,是因为它实现了这些接口。 同样道理,如果我们能编写一个助手测试类也实现了一些接口,那么我们就很容易测试action了。思想是活,不要太固化在一个地方。 下面给出一个相似的例子: 1,具备HttpServletRequest的控制器 package com.beetle.test.book.web; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*; import com.beetle.core.web.controller.*; import com.beetle.core.web.modelview.*; public class DemoServlet extends ControllerImp { public DemoServlet() { } public ModelView handleRequest(HttpServletRequest request) throws ServletException, IOException { String name = request.getParameter("userName"); String password = request.getParameter("password"); Map model = new HashMap(); model.put("returnObj", name + "[" + password + "]"); model.put("djkljfl",new Integer(1000)); ModelView mv = new ModelView("xxxview", model); return mv; } } 2,编写一个通用测试助手类DebugController package com.beetle.core.web; /** * <p>Title: FrameWork</p> * <p>Description: 基础系统框架项目</p> * <p>Copyright: Copyright (c) 2003</p> * <p>Company: 甲壳虫软件</p> * @author 余浩东 * @version 1.0 */ import java.io.*; import java.security.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import com.beetle.core.web.controller.ControllerImp; import com.beetle.core.web.modelview.ModelView; public class DebugController { private VirRequest request = new VirRequest(); private Map model; public DebugController() { } public void setParameter(String parameterName, String value) { request.setParameter(parameterName, value); } public void debug(ControllerImp controller) { try { ModelView mv = controller.handleRequest(request); System.out.println("ViewName:" + mv.getViewname()); System.out.println("------"); model = mv.getModel(); Set keys = model.keySet(); Iterator itr = keys.iterator(); while (itr.hasNext()) { String modelname = (String) itr.next(); Object val = model.get(modelname); System.out.println("ModelName:" + modelname); System.out.println("ModelValue:" + val); System.out.println("--"); } } catch (Exception e) { e.printStackTrace(); } request.clear(); } public Object getModelValue(String modelName) { if (model == null) { throw new com.beetle.core.AppRuntimeException("run debug method first!"); } return model.get(modelName); } protected void finalize() throws Throwable { if (model != null) { model.clear(); } super.finalize(); } } class VirRequest implements HttpServletRequest { private Map datas = new HashMap(); public VirRequest() { } public void clear() { datas.clear(); } public void setParameter(String parameterName, String value) { datas.put(parameterName, value); } /** * getAttribute * * @param string String * @return Object * @todo Implement this javax.servlet.ServletRequest method */ public Object getAttribute(String string) { return null; } //public void set /** * getAttributeNames * * @return Enumeration * @todo Implement this javax.servlet.ServletRequest method */ public Enumeration getAttributeNames() { return null; } /** * getAuthType * * @return String * @todo Implement this javax.servlet.http.HttpServletRequest method */ public String getAuthType() { return ""; } /** * getCharacterEncoding * * @return String * @todo Implement this javax.servlet.ServletRequest method */ public String getCharacterEncoding() { return ""; } /** * getContentLength * * @return int * @todo Implement this javax.servlet.ServletRequest method */ public int getContentLength() { return 0; } /** * getContentType * * @return String * @todo Implement this javax.servlet.ServletRequest method */ public String getContentType() { return ""; } /** * getContextPath * * @return String * @todo Implement this javax.servlet.http.HttpServletRequest method */ public String getContextPath() { return ""; } /** * getCookies * * @return Cookie[] * @todo Implement this javax.servlet.http.HttpServletRequest method */ public Cookie[] getCookies() { return null; } /** * getDateHeader * * @param string String * @return long * @todo Implement this javax.servlet.http.HttpServletRequest method */ public long getDateHeader(String string) { return 0L; } /** * getHeader * * @param string String * @return String * @todo Implement this javax.servlet.http.HttpServletRequest method */ public String getHeader(String string) { return ""; } /** * getHeaderNames * * @return Enumeration * @todo Implement this javax.servlet.http.HttpServletRequest method */ public Enumeration getHeaderNames() { return null; } /** * getHeaders * * @param string String * @return Enumeration * @todo Implement this javax.servlet.http.HttpServletRequest method */ public Enumeration getHeaders(String string) { return null; } /** * getInputStream * * @return ServletInputStream * @throws IOException * @todo Implement this javax.servlet.ServletRequest method */ public ServletInputStream getInputStream() throws IOException { return null; } /** * getIntHeader * * @param string String * @return int * @todo Implement this javax.servlet.http.HttpServletRequest method */ public int getIntHeader(String string) { return 0; } /** * getLocale * * @return Locale * @todo Implement this javax.servlet.ServletRequest method */ public Locale getLocale() { return null; } /** * getLocales * * @return Enumeration * @todo Implement this javax.servlet.ServletRequest method */ public Enumeration getLocales() { return null; } /** * getMethod * * @return String * @todo Implement this javax.servlet.http.HttpServletRequest method */ public String getMethod() { return ""; } /** * getParameter * * @param string String * @return String * @todo Implement this javax.servlet.ServletRequest method */ public String getParameter(String parameterName) { return (String) datas.get(parameterName); } /** * getParameterMap * * @return Map * @todo Implement this javax.servlet.ServletRequest method */ public Map getParameterMap() { return datas; } /** * getParameterNames * * @return Enumeration * @todo Implement this javax.servlet.ServletRequest method */ public Enumeration getParameterNames() { Vector v = new Vector(); Iterator it = datas.keySet().iterator(); while (it.hasNext()) { v.add(it.next()); } return v.elements(); } /** * getParameterValues * * @param string String * @return String[] * @todo Implement this javax.servlet.ServletRequest method */ public String[] getParameterValues(String parameterName) { String a = (String) datas.get(parameterName); StringTokenizer st = new StringTokenizer(a, ","); ArrayList li = new ArrayList(); while (st.hasMoreTokens()) { li.add(st.nextToken()); } return (String[]) li.toArray(); } /** * getPathInfo * * @return String * @todo Implement this javax.servlet.http.HttpServletRequest method */ public String getPathInfo() { return ""; } /** * getPathTranslated * * @return String * @todo Implement this javax.servlet.http.HttpServletRequest method */ public String getPathTranslated() { return ""; } /** * getProtocol * * @return String * @todo Implement this javax.servlet.ServletRequest method */ public String getProtocol() { return ""; } /** * getQueryString * * @return String * @todo Implement this javax.servlet.http.HttpServletRequest method */ public String getQueryString() { return ""; } /** * getReader * * @return BufferedReader * @throws IOException * @todo Implement this javax.servlet.ServletRequest method */ public BufferedReader getReader() throws IOException { return null; } /** * getRealPath * * @param string String * @return String * @todo Implement this javax.servlet.ServletRequest method */ public String getRealPath(String string) { return ""; } /** * getRemoteAddr * * @return String * @todo Implement this javax.servlet.ServletRequest method */ public String getRemoteAddr() { return ""; } /** * getRemoteHost * * @return String * @todo Implement this javax.servlet.ServletRequest method */ public String getRemoteHost() { return ""; } /** * getRemoteUser * * @return String * @todo Implement this javax.servlet.http.HttpServletRequest method */ public String getRemoteUser() { return ""; } /** * getRequestDispatcher * * @param string String * @return RequestDispatcher * @todo Implement this javax.servlet.ServletRequest method */ public RequestDispatcher getRequestDispatcher(String string) { return null; } /** * getRequestURI * * @return String * @todo Implement this javax.servlet.http.HttpServletRequest method */ public String getRequestURI() { return ""; } /** * getRequestURL * * @return StringBuffer * @todo Implement this javax.servlet.http.HttpServletRequest method */ public StringBuffer getRequestURL() { return null; } /** * getRequestedSessionId * * @return String * @todo Implement this javax.servlet.http.HttpServletRequest method */ public String getRequestedSessionId() { return ""; } /** * getScheme * * @return String * @todo Implement this javax.servlet.ServletRequest method */ public String getScheme() { return ""; } /** * getServerName * * @return String * @todo Implement this javax.servlet.ServletRequest method */ public String getServerName() { return ""; } /** * getServerPort * * @return int * @todo Implement this javax.servlet.ServletRequest method */ public int getServerPort() { return 0; } /** * getServletPath * * @return String * @todo Implement this javax.servlet.http.HttpServletRequest method */ public String getServletPath() { return ""; } /** * getSession * * @return HttpSession * @todo Implement this javax.servlet.http.HttpServletRequest method */ public HttpSession getSession() { return null; } /** * getSession * * @param _boolean boolean * @return HttpSession * @todo Implement this javax.servlet.http.HttpServletRequest method */ public HttpSession getSession(boolean _boolean) { return null; } /** * getUserPrincipal * * @return Principal * @todo Implement this javax.servlet.http.HttpServletRequest method */ public Principal getUserPrincipal() { return null; } /** * isRequestedSessionIdFromCookie * * @return boolean * @todo Implement this javax.servlet.http.HttpServletRequest method */ public boolean isRequestedSessionIdFromCookie() { return false; } /** * isRequestedSessionIdFromURL * * @return boolean * @todo Implement this javax.servlet.http.HttpServletRequest method */ public boolean isRequestedSessionIdFromURL() { return false; } /** * isRequestedSessionIdFromUrl * * @return boolean * @todo Implement this javax.servlet.http.HttpServletRequest method */ public boolean isRequestedSessionIdFromUrl() { return false; } /** * isRequestedSessionIdValid * * @return boolean * @todo Implement this javax.servlet.http.HttpServletRequest method */ public boolean isRequestedSessionIdValid() { return false; } /** * isSecure * * @return boolean * @todo Implement this javax.servlet.ServletRequest method */ public boolean isSecure() { return false; } /** * isUserInRole * * @param string String * @return boolean * @todo Implement this javax.servlet.http.HttpServletRequest method */ public boolean isUserInRole(String string) { return false; } /** * removeAttribute * * @param string String * @todo Implement this javax.servlet.ServletRequest method */ public void removeAttribute(String string) { } /** * setAttribute * * @param string String * @param object Object * @todo Implement this javax.servlet.ServletRequest method */ public void setAttribute(String string, Object object) { } /** * setCharacterEncoding * * @param string String * @throws UnsupportedEncodingException * @todo Implement this javax.servlet.ServletRequest method */ public void setCharacterEncoding(String string) throws UnsupportedEncodingException { } } 3,编写具体测试代码 package com.beetle.test.book.web; import com.beetle.core.web.*; public class DebugServlet { public static void main(String[] args) { DebugController dc = new DebugController(); dc.setParameter("userName", "Henry"); dc.setParameter("password", "888888"); dc.debug(new DemoServlet()); } } 结果 ViewName:xxxview ------ ModelName:returnObj ModelValue:Henry[888888] -- ModelName:djkljfl ModelValue:1000 -- |
|
返回顶楼 | |
发表时间:2005-01-21
用得着费这么大劲么,现成的就有HttpUnit啦什么的一大堆。越是有这些workaround,越说明它确实难测。
|
|
返回顶楼 | |
发表时间:2005-01-21
gigix 写道 用得着费这么大劲么,现成的就有HttpUnit啦什么的一大堆。越是有这些workaround,越说明它确实难测。
并不费劲呀,上面真正工作的代码也就是那几行,只是httpservletrequst接口太大,把程序拖长罢了。应该是, 越是有这些workaround,越说明它容易被测试! |
|
返回顶楼 | |
发表时间:2005-02-16
晕,说真的,测试是哪都不能少的,早点发现,后面可以少做的工作是多少,大家都知道,STRUTS我不知道别人怎么做,我就知道我做起来的时候总是写好ACTION加FORM,再写上JSP跑起来才能发现哪有错,想早发现也没办法,不知道大家怎么做的,可能我是只很菜的鸟吧,有什么办法可以加快让我发现这些错误呢?webwork我还没学会用,正想试一下,可能只有我试过后我才会知道哪个更好用一点吧,只是听大家说的,真的好晕哦,萝卜青菜各有所爱
|
|
返回顶楼 | |