StrutsTestCase 之discovery

转载 2006年06月15日 09:39:00
StrutsTestCase 之discovery
StrutsTestCase用于对基于Struts框架的Web应用进行单元测试,它可以用来测试ActionForm,Action的Execute方法,Action Forward, 及转向后的JSP是否正确。一个典型的Case代码如下:
 
        setRequestPathInfo("/DriveBus");
        addRequestParameter("driver", "tang");
        actionPerform();
        verifyForward("success");
 
就这样的短短几行代码,在实际运行过程中却遇到很多问题。
 
1. junit.framework.AssertionFailedError: Error initializing action servlet: Unable to find /WEB-INF/web.xml.  TestCase is running from D:/ide/eclipse3.0.1/workspace/ztest directory.  Context directory has not been set.  Try calling setContextDirectory() with a relative or absolute path.  /WEB-INF/web.xml must be found under the context directory, the directory the test case is running from, or in the classpath.
 这个错误原因是没有找到web-inf/web.xml所在的目录。一般被测代码和测试的代码不是在一个工程下的。如下图的结构所示:
   projects
   |-myWeb
   |   |-src
   |   |-WEB-INF
   |      |-classes
   |      |-lib
   |  
   |      | struts-confg.xml
   |      | web.xml
   |  
   |-test
       |-src
 
test工程包含所有用来测试myWeb工程的TestCase,这时候就需要覆写MockStrutsTestCase里的setup()方法:
    protected void setUp() throws Exception
    {
        // TODO Auto-generated method stub
        super.setUp();
        setContextDirectory(new File("../myWeb"));
    }
SetContextDirectory()方法保证TestCase能正确找到web.xml和struts-config.xml文件。
 
2。setRequestPathInfo()用来设置页面的form提交时执行的action,如jsp中form代码为:<FORM action="DriveBus.do" method="post">,则应该写成setRequestPathInfo("/DriveBus").
注意该函数的参数:
   1)DriveBus前面的左斜杠是必需的。
   2)不能包含context路径。
   3)在后面加上.do是没有问题的。
 
3。setRequestPathInfo()存在的问题
 当调用该方法时,会调用Common中的stripActionPath()进行处理,当setRequestPathInfo()的传入参数为“/DriveBus.do”时,会被截成“/DriveBus”,它将会设置到request的pathinfo字段。问题就在这里。
在StrutsTestCase中,对容器内的request进行了模拟,用HttpServletRequestSimulator代替真正的HttpServletRequest。对于部署在容器里的应用,如下函数的输出分别为:
    request.getPathInfo()    null
    request.getRequestURI()     /myWeb/DriveBus.do
    request.getRequestURL()     http://localhost:8080/myWeb/DriveBus.do
    request.getServletPath()    /DriveBus.do
而模拟的request得出的输出为:
    request.getPathInfo()    /DriveBus
    request.getRequestURI()     null
    request.getRequestURL()    null
    request.getServletPath()     null
可见,HttpServletRequestSimulator并没有能够很好地模拟request,当被测程序中调用了request.getPathInfo()以外的方法时,测试很可能不会通过(抛NullPointerException异常),或者会出现错误的测试结果。
 
4。多模块测试
StrutsTestCase支持对多模块的测试,在setRequestPathInfo()中可以指定模块名称,setRequestPathInfo(String moduleName, String pathInfo),其部分代码如下:
    this.actionPath = Common.stripActionPath(pathInfo);
        if (moduleName != null) {
            if (!moduleName.equals("")) {
                if (!moduleName.startsWith("/"))
                    moduleName = "/" + moduleName;
                if (!moduleName.endsWith("/"))
                    moduleName = moduleName + "/";
            }
            if (logger.isDebugEnabled()) {
                logger.debug("setting request attribute - name = " + Common.INCLUDE_SERVLET_PATH + ", value = " + moduleName);
            }
            this.request.setAttribute(Common.INCLUDE_SERVLET_PATH, moduleName);
        }
        this.request.setPathInfo(actionPath);
        this.requestPathSet = true;
它将传入的模块名名设置到request的Common.INCLUDE_SERVLET_PATH属性,但是在verifyForwardPath()的代码中却有这样一段:
   String moduleName = request.getServletPath() != null ? request.getServletPath() : "";
        if ((moduleName == null || moduleName.equalsIgnoreCase("")) && request.getAttribute(INCLUDE_SERVLET_PATH) != null)
            // check to see if this is a MockStrutsTestCase call
            moduleName = (String) request.getAttribute(INCLUDE_SERVLET_PATH);
当可以取到ServletPath时,将其值作为moduleName,这个真是让人想不通!!servletPath和模块名有什么关系呢?
 
 (对于URI, URL, URN的详细说明见:http://www.ietf.org/rfc/rfc1738.txt,所以StrutsTestCase对HttpServletRequest的模拟是不符合规范的)
 
5。contextPath
这个值始终是空字符串
 
总之,当我们使用StrutsTestCase进行测试时,需要对以上问题多加留意,当出错时,可能会是StrutsTestCase本身的问题,必要的话,可以对其进行源码进行修改,以适合我们系统本身的需求。StrutsTestCase的license是 Apache Software License。
 
附: Apache Software License (ASL)可以兼容其它任何已知的许可证。 已知的最大例外是GNU Public License (GPL) 和Lesser GNU Public License (LGPL). 重要的是ASL对合作开发相当友好,如果您不想的话,也不会强迫您发布源代码。 Apache Software Foundation名下的德高望众的HTTP服务器用的是相同的许可证。
(完)

ONVIF学习之实现discovery

ONVIF实现的第一步当然是discovery,但是实现discovery分为被发现和主动发现。 实现被发现,我参考的博客是,很完整,根据这个就可以实现。 http://blog....
  • Leo_Luo1
  • Leo_Luo1
  • 2016年04月27日 23:53
  • 1767

Win7 网络发现无法启用的解决方法

今天在共享打印机的时候出了点问题,其中一部是要打开本机的网络发现功能,但是选择“启用网络发现”之后,关闭对话框再重新打开的时候又被改成了“关闭网络发现” 经过网上一翻查询,原因如下:...
  • zhouyingge1104
  • zhouyingge1104
  • 2014年12月11日 18:25
  • 13151

作業系統之前的程式 for stm32f4discovery (0) - 打造 linux 開發環境

the 1st edition: 20130405 the 2nd edition: 20150119 這個系列累積了不少篇幅, 以下是所有系列的文章目錄: bare-metal for stm32...
  • descent0
  • descent0
  • 2015年10月22日 17:37
  • 1040

StrutsTestCase配置的常见问题及其多级Action的处理方式

StrutsTestCase的配置的常见问题及其简单的测试用例
  • simon_world
  • simon_world
  • 2014年11月19日 22:26
  • 1286

Struts2+Spring的UnitTest编写(使用StrutsTestCase的子类StrutsSpringTestCase)

我们都知道struts2有自己的对象工厂即obejectFactory,但是你也可以使用spring来作为对象工厂,继承了spring之后的单元测试要加什么东西呢?       答案是要加入下面的这...
  • Ethan_Fu
  • Ethan_Fu
  • 2013年04月18日 10:26
  • 1086

StrutsTestCase工程例子

  • 2008年11月04日 10:31
  • 1.75MB
  • 下载

C++构造DHCP Discovery报文并使用socket发送

DHCP由BOOTP协议发展而来,而后者基于UDP、IP协议,这使得使用socket发送DHCP报文成为可能。本文示例构造了DHCP Discovery报文并调用socket接口发送,值得注意的是,由...
  • rrrfff
  • rrrfff
  • 2012年07月15日 18:45
  • 46432

Elasticsearch模块功能之-自动发现(Discovery)

一 自动发现(Disovery) 该模块主要负责集群中节点的自动发现和Master节点的选举。节点之间使用p2p的方式进行直接通信,不存在单点故障的问题。Elasticsearch中,Master节...
  • changong28
  • changong28
  • 2014年08月05日 01:00
  • 17918

Zabbix 探索主机 “Discovery” 自动发现主机 详细图文教程

Zabbix 自动发现(Discovery)功能使用         随着监控主机不断增多,有的时候需要添加一批机器,特别是刚用zabbix的童鞋 需要将公司的所有服务器添加到zabbix,如果...
  • zk673820543
  • zk673820543
  • 2016年02月15日 10:02
  • 11010

总结教训:stm32f4-Discovery驱动三星s6d1121液晶程序

搞了几天!最后总结一句!看文档不仔细,就是坑爹!是严重坑爹!   刚开始,这块液晶,我拿stc12c5a60s2来驱动,能点亮! 然后把51上的驱动,移植到F4里。到F4下测,死活都是白屏,刚开...
  • wzs298
  • wzs298
  • 2013年09月22日 03:49
  • 4327
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:StrutsTestCase 之discovery
举报原因:
原因补充:

(最多只允许输入30个字)