eclipse+JUnit测试Seam

折腾了一天,junit终于可以跑起来了,分享一下,希望对大家能有帮助。
项目基于Maven搭建(Maven确实是个好东西)。使用的技术有jsf + richfaces3.3 + seam2.2 + hibernate3.3 + jasperreport3.7。感觉seam很强大,但没有spring方便,至少在测试方面要花费一翻功夫。
我没有将测试代码放到项目的测试目录下,而是另起了一个工程,专用于测试,以下就完整的介绍一下这个过程。更多是步骤描述了,为什么要这样做就不多解释了,也没能力解释清楚。
1. 建立测试工程:seamtest。最简单的maven工程即可。这里不介绍如何在eclipse中集成maven,读者可以搜搜m2eclipse,这是一个eclipse插件。

2. 配置seamtest的pom.xml,增加如下三个依赖:
< dependency >
    
< groupId > org.jboss.seam.embedded </ groupId >
    
< artifactId > hibernate-all </ artifactId >
    
< version > beta3.SP10 </ version >
</ dependency >
< dependency >
  
< groupId > org.jboss.seam.embedded </ groupId >
  
< artifactId > jboss-embedded-all </ artifactId >
  
< version > beta3.SP10 </ version >
</ dependency >
< dependency >    
  <
groupId > org.jboss.seam.embedded </ groupId >
  
< artifactId > thirdparty-all </ artifactId >
  
< version > beta3.SP10 </ version >
</ dependency >

3. 这三个依赖需要从jboss仓库下载,可以访问这个站点:https://repository.jboss.org/nexus/index.html,然后根据上面提供的构件Id进行搜索,或者直接将仓库指向:https://repository.jboss.org/nexus/content/repositories/releases/。如何在settings.xml文件中配置仓库地址不难,google下吧。

4. 将需要测试的项目及junit加到maven依赖中,我的配置为:
< dependency >
  
< groupId > cn.terry </ groupId >
  
< artifactId > target-web </ artifactId >
  
< version > 0.0.1-SNAPSHOT </ version >
  
< type > war </ type >
</ dependency >
< dependency >
  
< groupId > junit </ groupId >
  
< artifactId > junit </ artifactId >
  
< version > 4.8.2 </ version >
  
< type > jar </ type >
</ dependency >
上面的“target-web”就是我要测试的基于maven构建的项目。

5. 保存配置后等待eclipse下载完所有依赖的jar包。

6. 将目标工程加到测试工程的依赖工程中。参考下图:


7. 下载Embedded JBoss,下载地址: http://sourceforge.net/projects/jboss/files/Embedded%20JBoss/Embedded%20JBoss%20Beta%203/。

8. 解压缩下载的压缩后,找到文件夹:bootstrap,除这个文件夹外,其它下载文件在我们这个案例里面都不需要用到。

9. 将bootstrap文件夹链接到测试工程的source下面,参考如下操作界面:


10. 将target-web的webapp目录链接到测试工程的source下面,这一步比较奇怪,不多解释了,照着做就行了。

11. 配置DataSource。在bootstrap/deploy下面有文件hsqldb-ds.xml,注意文件名的结尾部分是“-ds.xml”,你可以按这个命名规则建立自己需要的datasource文件,如oracle-ds.xml。datasource文件具体怎么写,就要参考hsqldb-ds.xml了,这个还是比较容易的。如果你的项目不需要dataSource的话就跳过这一步吧。

12. 接下来开始写测试代码了,如下二个类直接复制过去用:
MySeamTestBase: 其它测试类可以直接继承该类
package  cn.terry.test;

import  java.util.Properties;

import  org.jboss.seam.mock.AbstractSeamTest;
import  org.junit.After;
import  org.junit.AfterClass;
import  org.junit.Before;
import  org.junit.BeforeClass;
import  org.junit.Test;

public   class  MySeamTestBase  extends  AbstractSeamTest {
    
//  static helper instance to call non static methods in
    
//  a static method
     private   static  MySeamTestBase seamTest  =   new  MySeamTestBase();
    
private   static   boolean  batch  =   false ;

    
/*
     * JUnit test life cycle methods.
     
*/

    @BeforeClass
    
public   static   void  setUpBeforeClass()  throws  Exception {
        
if  ( ! batch) {
            seamTest.startContainer();
        }
    }

    @AfterClass
    
public   static   void  tearDownAfterClass()  throws  Exception {
        
if  ( ! batch)
            seamTest.stopContainer();
    }

    @Before
    
public   void  setUp()  throws  Exception {
        setupClass();
        begin();
    }

    @After
    
public   void  tearDown()  throws  Exception {
        end();
        cleanupClass();
    }

    
/*
     * Helper methods
     
*/

    
//  starts the JBoss embedded ejb container
     public   void  startContainer()  throws  Exception {
        
super .startSeam();        
    }

    
//  stops the JBoss embedded ejb container
     public   void  stopContainer()  throws  Exception {
        
super .stopSeam();
    }
    
    
public   boolean  isBatch() {
        
return  batch;
    }

    
//  used by a JUnit.Suite runner to set the batch flag
     public   void  setBatch( boolean  fBatch) {
        batch 
=  fBatch;
    }
}


MySuiteRunner, 批量执行多个测试类:
package  cn.terry.test;

import  org.junit.AfterClass;
import  org.junit.BeforeClass;
import  org.junit.runner.RunWith;
import  org.junit.runners.Suite;

import  cn.terry.test.testcase.HelloTest;

 
@Suite.SuiteClasses({ 
    HelloTest.
class
})
@RunWith(Suite.
class )
public   class  MySuiteRunner {
    
private   static  MySeamTestBase seamTest  =   new  MySeamTestBase();
 
    @BeforeClass
    
public   static    void  setUpBeforeClass()  throws  Exception {    
        
//  set the flag to signal batch mode
        seamTest.setBatch( true );
        seamTest.startContainer();
    }
 
    @AfterClass
    
public   static   void  tearDownAfterClass()  throws  Exception {        
        seamTest.stopContainer();
        seamTest.setBatch(
false );
    }
}

下面的HelloTest是一个具体的测试类,模仿着写就行了:
package  cn.terry.test.testcase;

import  org.junit.Test;

import  cn.terry.test.MySeamTestBase;

public   class  HelloTest  extends  MySeamTestBase {
    @Test
    
public   void  testRollback()  throws  Exception{
        
new  FacesRequest() {
            
protected   void  invokeApplication()  throws  Exception {
                Object seamInstance 
=  getInstance( " instanceName " );
            }
        }.run();
    }

}
FacesRequest里面还有许多方法可以重写,自己翻翻手册吧。


13. 到执行这一步了,也不容易,如果是jdk6的话,要在运行时加上运行参数:-Dsun.lang.ClassLoader.allowArraySyntax=true。eclipse中如何配置请参考如下界面:

点击run,享受成果吧。

14,可能没有这么幸运,数据库连接池可能没有初始化。在我们的项目中,连接池是在一个servlet listener中初始化的,通过如上方式运行就没法自动初始化,导致测试时出现数据库连接失败的情况,这时候需要自己写些代码去初始化连接了。

总结:整个过程可能会出现没完没了的异常,别放弃,多google,总会成功的。

你可能感兴趣的:(eclipse+JUnit测试Seam)