在Eclipse的编译器下,用的struts2+spring框架,做单元测试(Junit4)
参考前辈的方法(很有用,很感谢)
http://dendrobium.javaeye.com/blog/428386
但仍有问题。
(请不熟悉的朋友,一定要先看上面这个blog)完全模仿他的格式,其中他里面personalService相当于我的DBUtil,用来连接数据库的。
他的personAction相当于我的LoginAction,都是用户登录时调用的。
模仿他的testLogin(),如下 @Test
public void testLogin() {
String result = "";

//模拟用户的登陆信息  
action.setUname("xyz");
action.setPwd("123456");
action.setDbu(util);

//模拟输入验证码   
action.setValcode("111111");
//向session中输入验证码   
        Map session=new HashMap();   
        session.put("randNum", "111111");   
        context.setSession(session);        //运行action
        try {
         result = action.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

//看看结果是否符合预期   
Assert.assertEquals( "success", result);
        Assert.assertEquals( "欢迎回来,"+action.getUname()+"。现在将要跳转到主页", action.getMessage());
        Assert.assertEquals("adminLogin.jsp", action.getUrl());
}不好用。
经查找发现,context变量一直为null。所以,我断定是DYBaseActionTest中的getApplicationContext()出了问题。
我的DYBaseActionTest代码如下:public class DYBaseActionTest {
    private ApplicationContext context = null;   
  
    @Before
    public void setUp() throws Exception   
    {      
         context = new FileSystemXmlApplicationContext("web/WEB-INF/appcontext.xml"); 
    }   
    
    public ApplicationContext getApplicationContext()   
    {   
        return context;   
    }   
}
于是我对public void setUp() 函数进行了测试,测试过程如下:     @Test
    public void main() throws Exception
    {
    
     DYBaseActionTest t = new DYBaseActionTest();
     t.setUp();
     System.out.println("结束");
    }结果如下:
具体的说
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'easyGoingDataSource' defined in file [E:\work\workspace\easygoing\web\WEB-INF\appcontext.xml]: Invocation of init method failed; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean
(AbstractAutowireCapableBeanFactory.java:1336)
          。
          。
          。
at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:140)
at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:84)
at com.easygoing.form.action.DYBaseActionTest.setUp(DYBaseActionTest.java:16)
          。
          。
          。
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:645)
... 38 more理论上说,问题出在了ApplicationContext.xml,但是工程是可用的,好用的,我的spring配置xml文件如下:<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
   "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">     <!--通过JNDI获得数据源的引用-->
     <bean id="easyGoingDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
         <property name="jndiName">
              <value>java:comp/env/jdbc/easyGoing</value>
         </property>
     </bean>
    <!-- 配置JdbcTemplate的bean -->
     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource">
           <ref local="easyGoingDataSource"/>
        </property>
     </bean>
     <!-- 配置DBUtil的bean 并注入资源-->
     <bean id="DBUtil" class="com.easygoing.util.DBUtil">
        <property name="jt">
           <ref local="jdbcTemplate"/>
        </property>
        <property name="ds">
         <ref local="easyGoingDataSource"/>
        </property>
     </bean>
    <!--用户登陆的Action为Spring的受管Bean并注入资源 -->
    <bean id="Login" class="com.easygoing.form.action.LoginAction" singleton="false">
        <property name="dbu">
           <ref local="DBUtil"/>
        </property>
    </bean>
    /*****还有些类似的,与本文无关*****/
</beans>文件的位置也正确,文件名叫做appcontext.xml。查了一天的资料也每个结果,恳请大家帮忙~

解决方案 »

  1.   

    感觉是new FileSystemXmlApplicationContext("web/WEB-INF/appcontext.xml"); 这个地方的问题.!  路径不对吧
      

  2.   

    路径是对的,因为在console的错误提示中中可以找到这样一句话:2010-6-26 22:11:26 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    信息: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@e1d5ea: display name [org.springframework.context.support.FileSystemXmlApplicationContext@e1d5ea]; startup date [Sat Jun 26 22:11:26 CST 2010]; root of context hierarchy
    2010-6-26 22:11:26 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    信息: Loading XML bean definitions from file [E:\work\workspace\easygoing\web\WEB-INF\appcontext.xml]
    2010-6-26 22:11:26 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
    信息: Bean factory for application context [org.springframework.context.support.FileSystemXmlApplicationContext@e1d5ea]: org.springframework.beans.factory.support.DefaultListableBeanFactory@64ab4d
    2010-6-26 22:11:26 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
    信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@64ab4d: defining beans [easyGoingDataSource,jdbcTemplate,DBUtil,UUAction,Reg,Login,Index,TTLAction,TTDAction,EAction,AAction,GMCAction,GMIAction,CPWDAction,CIFAction,TMCAction,TAFAction,TMQAction,TMAAction,MyApplyAction,TNAAction,GTAction,ASAction,MSAction,ALAction,AMAction,TULAction,TCLAction,ECAction,TQLAction,TRLAction]; root of factory hierarchy
    2010-6-26 22:11:26 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
    信息: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@64ab4d: defining beans [easyGoingDataSource,jdbcTemplate,DBUtil,UUAction,Reg,Login,Index,TTLAction,TTDAction,EAction,AAction,GMCAction,GMIAction,CPWDAction,CIFAction,TMCAction,TAFAction,TMQAction,TMAAction,MyApplyAction,TNAAction,GTAction,ASAction,MSAction,ALAction,AMAction,TULAction,TCLAction,ECAction,TQLAction,TRLAction]; root of factory hierarchy
    证明它是找到了,但由于其中的第一个bean生成时遇到了问题,所以就立刻destroy了我在想是不是类库不够?基本的我都有啊
    搞了好久,类库都加了好多文件了,还是不行,估计是个细节问题,大家帮帮忙~
      

  3.   

    Error creating bean with name 'easyGoingDataSource' defined in file [E:\work\workspace\easygoing\web\WEB-INF\appcontext.xml]: Invocation of init method failed; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial应该是创建easyGoingDataSource出错 初始化方法调用失败。因为没初始化上下文异常。试试下面的操作:如果你用的是tomcat服务器那么在lookup的时候要加入java:comp/env/
     DataSource datasource=(DataSource)context.lookup("java:comp/env/jdbc/xxxx"); 
    需要配置查找参数Properties props = new Properties();
       props.setProperty("java.naming.factory.initial",
         "com.sun.enterprise.naming.SerialInitContextFactory");
       props.setProperty("java.naming.factory.url.pkgs",
         "com.sun.enterprise.naming");
       props.setProperty("java.naming.factory.state",
         "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");   props.setProperty("org.omg.CORBA.ORBInitialHost", "localhost");//这里是GlassFish运行的主机地址
       props.setProperty("org.omg.CORBA.ORBInitialPort", "3700");   try {
        InitialContext ctx = new InitialContext(props);
        DataSource ds=(DataSource)ctx.lookup("jdbc/xxx");//这里就是数据源的名子
          } catch (NamingException e) {
         e.printStackTrace();
       } 
     
      

  4.   


        //@Before
        public void setUp() throws Exception   
        {      
         System.out.println("开始");
          
            /*context = new FileSystemXmlApplicationContext("web/WEB-INF/appcontext.xml");
            DataSource datasource=(DataSource)context.lookup("java:comp/env/jdbc/easgGoing");
            
            */
         Properties props = new Properties();
            props.setProperty("java.naming.factory.initial",
            "com.sun.enterprise.naming.SerialInitContextFactory");
            props.setProperty("java.naming.factory.url.pkgs",
            "com.sun.enterprise.naming");
            props.setProperty("java.naming.factory.state",
            "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");         //props.setProperty("org.omg.CORBA.ORBInitialHost", "localhost");//这里是GlassFish运行的主机地址
            //props.setProperty("org.omg.CORBA.ORBInitialPort", "8088");         try {
            InitialContext ctx = new InitialContext(props);
            DataSource ds=(DataSource)ctx.lookup("jdbc/env/jdbc/easgGoing");//这里就是数据源的名子
            System.out.println(ctx.toString());
            } catch (NamingException e) {
            e.printStackTrace();
            }  
    这样写吗?
    运行结果:<===================================================================================>
    开始
    javax.naming.NoInitialContextException: Cannot instantiate class: com.sun.enterprise.naming.SerialInitContextFactory [Root exception is java.lang.ClassNotFoundException: com.sun.enterprise.naming.SerialInitContextFactory]
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:657)
                    ...
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Caused by: java.lang.ClassNotFoundException: com.sun.enterprise.naming.SerialInitContextFactory
    at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
    ...
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:654)
    ... 28 more

    结束
    <===================================================================================>我是用的tomcat服务器,tomcat 5.5
    catalina_home、ant_home、java_home都识别。
    现在就是想模拟一个web环境,做恶心的单元测试。现在是心灰意冷啊,愁~
    又能解决这个问题的加我qq吧。603637582,加的时候注明:“csdn帮你解决测试的朋友”
      

  5.   

    测试Struts这种事从来不干,Service或Manager测试就可以了
      

  6.   

    另外值得一提的是(对不起忘说了),我的数据库连接context是在tomcat里面写的,在其中的conf/server.xml里面写的
    <Context path="/easygoing" docBase="easygoing"
             debug="5" reloadable="true" crossContext="true"   workDir="">
       <Resource   name="jdbc/easyGoing"
                  auth="Container"
                  type="javax.sql.DataSource"
                  maxActive="100" maxIdle="30" maxWait="10000"
                  username="easygoing" password="123456"
         driverClassName="com.microsoft.jdbc.sqlserver.SQLServerDriver"
         url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=easyGoing"/>
    </Context> 
    这些信息,junit就得不到了估计,有没有办法呢?
      

  7.   

    找了一个关于tomcat 写数据源resource的方法的文章。和我的工程有关http://blog.csdn.net/guodongbingtuan/archive/2009/07/04/4320959.aspx我的属于第三种,是写在server.xml中的。
    所以在测试的时候,不开启tomcat的时候就获取不到这个资源了。
      

  8.   

    问题解决了!问题就是出在找不到数据源的问题上。
    因为jndi是在tomcat下配置的,但是用junit进行单元测试的环境下是独立于tomcat的,不能够与jndi中的数据相连。于是我就搜索各类 数据源context resource 写法 问题
    终于找到了这个:
    Spring+iBatis环境下的单元测试问题
    http://junherry.javaeye.com/blog/545639根据提示,然后copy了一份appcontex.xml,单独用作junit测试(叫做appcontext_junit),然后修改FileSystemXmlApplicationContext中的地址。然后出现了少org.apache.commons.dbcp.BasicDataSource的提示,然后找到jar包commons-dbcp-1.4.jar,加入,OK,一气呵成,最后“这种正常”!呵呵
    public class DYBaseActionTest {
        private ApplicationContext context = null;   
      
        @Before
        public void setUp() throws Exception   
        {       
            context = new FileSystemXmlApplicationContext("web/WEB-INF/appcontext_junit.xml");
        }   
        public ApplicationContext getApplicationContext()   
        {   
            return context;   
        } 
    }谢谢izard999、谢谢三少、谢谢关注的朋友~!