折騰了一天,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,增加如下三個依賴:
3. 這三個依賴需要從jboss倉庫下載,可以訪問這個站點:https://repository.jboss.org/nexus/index.html,然后根據上面提供的構件Id進行搜索,或者直接將倉庫指向:https://repository.jboss.org/nexus/content/repositories/releases/。如何在settings.xml文件中配置倉庫地址不難,google下吧。
4. 將需要測試的項目及junit加到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: 其它測試類可以直接繼承該類
MySuiteRunner, 批量執行多個測試類:
下面的HelloTest是一個具體的測試類,模仿著寫就行了:
13. 到執行這一步了,也不容易,如果是jdk6的話,要在運行時加上運行參數:-Dsun.lang.ClassLoader.allowArraySyntax=true。eclipse中如何配置請參考如下界面:

點擊run,享受成果吧。
14,可能沒有這么幸運,數據庫連接池可能沒有初始化。在我們的項目中,連接池是在一個servlet listener中初始化的,通過如上方式運行就沒法自動初始化,導致測試時出現數據庫連接失敗的情況,這時候需要自己寫些代碼去初始化連接了。
總結:整個過程可能會出現沒完沒了的異常,別放棄,多google,總會成功的。
項目基于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>
<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構建的項目。<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>
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;
}
}
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);
}
}
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里面還有許多方法可以重寫,自己翻翻手冊吧。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();
}
}
13. 到執行這一步了,也不容易,如果是jdk6的話,要在運行時加上運行參數:-Dsun.lang.ClassLoader.allowArraySyntax=true。eclipse中如何配置請參考如下界面:

點擊run,享受成果吧。
14,可能沒有這么幸運,數據庫連接池可能沒有初始化。在我們的項目中,連接池是在一個servlet listener中初始化的,通過如上方式運行就沒法自動初始化,導致測試時出現數據庫連接失敗的情況,這時候需要自己寫些代碼去初始化連接了。
總結:整個過程可能會出現沒完沒了的異常,別放棄,多google,總會成功的。