使用RunWith註解改變JUnit的默認執行類,並實現自已的Listener

使用RunWith註解改變JUnit的默認執行類,並實現自已的Listener在平時的單元測試,如果不使用RunWith註解,那麼JUnit將會採用默認的執行類Suite執行,如下類:
[java] view plaincopy
  1. public class TestClass {  
  2.     @Test public void  t1(){}  
  3. }  
JUnit允許用戶指定其它的單元測試執行類,只需要我們的測試執行類繼承類org.junit.runners.BlockJUnit4ClassRunner就可以了,Spring的執行類SpringJUnit4ClassRunner就是繼承了該類。我們平時用Spring也比較多,爲了能夠更加方便的引用配置文件,我們單元測試就使用了Spring實現的執行類。此時的單元測試執行類將會看起來是這樣:
[java] view plaincopy
  1. @RunWith(SpringJUnit4ClassRunner.class)  
  2. @ContextConfiguration(locations = { "classpath*:/spring1.xml""classpath*:/spring2.xml" })  
  3. @TestExecutionListeners( { DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class })  
  4. @Transactional  
  5. public class TestClass {  
  6.     @Inject  
  7.     //這個類會在執行時被注入,這裏是按類型注入,如果想按名稱注入,需要加上@Named註解,如@Named("class1")  
  8.     //實現類可以加上@Named("class1")註解,也可以是配置在配置文件中的  
  9.     Class1 class1;  
  10.       
  11.     @Test   
  12.     public void  t1(){}  
  13. }  

以下分別對使用到的幾個註解進行解釋:

@RunWith:這個是指定使用的單元測試執行類,這裏就指定的是SpringJUnit4ClassRunner.class;

@ContextConfiguration:這個指定Spring配置文件所在的路徑,可以同時指定多個文件;

@TestExecutionListeners:這個用於指定在測試類執行之前,可以做的一些動作,如這裏的DependencyInjectionTestExecutionListener.class,就可以對一測試類中的依賴進行注入,TransactionalTestExecutionListener.class用於對事務進行管理;這兩個都是Srping自帶的; 我們也可以實現自己的Listener類來完成我們自己的操作,只需要繼續類org.springframework.test.context.support.AbstractTestExecutionListener就可以了,具體可以參照DependencyInjectionTestExecutionListener.class的實現,後面我會貼出實例。 Listener實在實現類執行之前被執行、實現類的測試方法之前被執行,這與Listener的實現有關。

@Transactional:這裏的@Transactional不是必須的,這裏是和@TestExecutionListeners中的TransactionalTestExecutionListener.class配合使用,用於保證插入的數據庫中的測試數據,在測試完後,事務回滾,將插入的數據給刪除掉,保證數據庫的乾淨。如果沒有顯示的指定@Transactional,那麼插入到數據庫中的數據就是真實的插入了。

我們的單元測試,通常涉及到數據庫的操作,那我們就需要真實的從數據庫中讀取數據並進行邏輯處理,爲了保證數據庫的乾淨,也爲了保證測試數據的準確性與正確性,我們最好是在做測試之前插入我們自己準備的測試數據,然後在測試完成後,將數據刪除掉,這時我們就可以通過增加一個Listener,來準備我們需要的測試數據,並和上面的事務管理相結合,就不會真正的提交到數據庫中去了。

以下這個實例是一個簡單的Listener實現,只是功能是把我們配置在method上面的註解裏面的配置文件路徑給打印出來,因爲實現集成DBUnit並插入數據庫的代碼比較多,這裏我就不貼出來了。1.首先我們需要準備一個註解,用來標識其帶的參數爲測試準備的數據文件:DBUnitTestData.java

[java] view plaincopy
  1. @Retention(RetentionPolicy.RUNTIME)  
  2. @Target(ElementType.METHOD)  
  3. @Inherited  
  4. @Documented  
  5. public @interface DBUnitTestData {  
  6.   
  7.     public String[] dataSetLocations();  
  8. }  
2.編寫Listener,這個Listener的名字就定義爲DBUnitTestExecutionListener.class:DBUnitTestExecutionListener.java
[java] view plaincopy
  1. import org.springframework.test.context.TestContext;  
  2. import org.springframework.test.context.TestExecutionListener;  
  3.   
  4. public class DBUnitTestExecutionListener implements TestExecutionListener {  
  5.   
  6.     public void prepareTestInstance(TestContext testContext) throws Exception {  
  7.     }  
  8.   
  9.     public void beforeTestClass(TestContext testContext) throws Exception {  
  10.         // Nothing to do  
  11.     }  
  12.   
  13.     public void afterTestClass(TestContext testContext) throws Exception {  
  14.         // Nothing to do  
  15.     }  
  16.   
  17.     public void beforeTestMethod(TestContext testContext) throws Exception {  
  18.         DBUnitTestData dbUnitRefresh = testContext.getTestMethod().getAnnotation(DBUnitTestData.class);  
  19.         if (dbUnitRefresh == null) {  
  20.             return;  
  21.         }  
  22.         String[] dataSetLocations = dbUnitRefresh.dataSetLocations();  
  23.         loadTestData(testContext, dataSetLocations);  
  24.     }  
  25.   
  26.     public void afterTestMethod(TestContext testContext) throws Exception {  
  27.         // Nothing to do  
  28.     }  
  29.   
  30.     private void loadTestData(TestContext testContext, String[] dataSetLocations) {  
  31.         if (dataSetLocations == null || dataSetLocations.length == 0) {  
  32.             return;  
  33.         }  
  34.         for (String dataSetLocation : dataSetLocations) {  
  35.             //Do what you want to do with the data set files  
  36.             System.out.println(dataSetLocation);  
  37.         }  
  38.     }  
  39.   
  40. }  
3.將Listener實現類加入到測試類的@TestExecutionListeners裏面,在方法上面增加註解@DBUnitTestData,這個時候測試類將會是如下這樣:
[java] view plaincopy
  1. @RunWith(SpringJUnit4ClassRunner.class)  
  2. @ContextConfiguration(locations = { "classpath*:/spring1.xml""classpath*:/spring2.xml" })  
  3. @TestExecutionListeners( { DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class,DBUnitTestExecutionListener.class })  
  4. @Transactional  
  5. public class TestClass {  
  6.     @Inject  
  7.     //這個類會在執行時被注入,這裏是按類型注入,如果想按名稱注入,需要加上@Named註解,如@Named("class1")  
  8.     //實現類可以加上@Named("class1")註解,也可以是配置在配置文件中的  
  9.     Class1 class1;  
  10.       
  11.     @Test   
  12.     @DBUnitTestData(dataSetLocations={"classpath:/testData/testData1.xml","classpath:/testData/testData2.xml"})  
  13.     public void  t1(){}  
  14. }  
4.執行這個方法就可以看到@DBUnitTestData註解的數據文件路徑給打印出來了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章