Spring提供的測試幫助類
Spring在org.springframework.test包中為測試提供了幾個有用的類,它們都是JUnit TestCase的子類。通過層層擴展,不斷豐富測試的功能,我們可以通過下圖了解這些類的繼承關系:
圖 1 Spring測試工具類
下面,我們來逐個了解這棵承繼類樹中每個節點測試類的功用,第一個要認識的是直接擴展于TestCase的ConditionalTestCase測試類。
ConditionalTestCase
如果你直接通過擴展TestCase創建測試用例,則所有帶test前綴的測試方法都會被毫無例外地執行。而ConditionalTestCase可以讓你在某些情況下,有選擇地關閉掉一些測試方法,不讓他們在測試用例中執行。這給開發者帶來了很大的靈活性,因為他們可以在某次測試中關閉掉一些測試方法,而僅運行當前特別關注的測試方法,將問題域聚集到一定范圍內。
如果你要關閉某個測試方法行,僅需實現ConditionalTestCase的 isDisabledInThisEnvironment(String testMethodName)方法就可以了,ConditionalTestCase在運行每一個測試方法前會根據isDisabledInThisEnvironment()方法判斷是簡單放棄目標方法的運行,還是按正常方式執行之。該方法默認情況下對所有的測試方法都返回false,也即執行所有的測試方法。讓我們來看一個具體例子:
代碼清單 4 ConditionalTest1:有條件執行測試方法 package com.baobaotao.test;
import org.springframework.test.ConditionalTestCase;
public class ConditionalTest1 extends ConditionalTestCase {
①被忽略不執行的測試方法
private static String[] IGNORED_METHODS = {"testMethod1","testMethod3"};
@Override
protected boolean isDisabledInThisEnvironment(String testMethodName) {②所有在
for (String method : IGNORED_METHODS) { IGNORED_METHODS數組中
if (method.equals(testMethodName)) { 的方法都忽略執行。
return true;
}
}
return false;
}
public void testMethod1(){ ③不執行
System.out.println("method1");
}
public void testMethod2(){ ④執行
System.out.println("method2");
}
public void testMethod3(){ ⑤不執行
System.out.println("method3");
}
}
如果我們直接承繼JUnit的TestCase,③、④及⑤處的三個測試方法都會被執行,但現在我們通過繼承ConditionalTestCase編寫測試類,并覆蓋了isDisabledInThisEnvironment()方法,當測試方法名位于IGNORED_METHODS數組中時,測試方法就被旁路掉了。因此當運行ConditionalTest1時,你會發現只有④處的testMethod2()測試方法得到了執行,其它兩個測試方法看起來也被成功執行,只不過會程序日志會給出報告,告訴你哪些測試方法是真正被執行,而哪些方法被“偽執行”的。
ConditionalTestCase其實可用于任何程序的單元測試中,它本身并沒有和Spring容器有任何關聯,它僅添加了一個按條件執行測試方法的功能。
AbstractSpringContextTests
AbstractSpringContextTests擴展于ConditionalTestCase,它維護了一個static類型的緩存器(HashMap),它使用鍵保存Spring ApplicationContext實例,這意味著Spring ApplicationContext是JVM級的,不同測試用例、不同測試方法都可以共享這個實例。也就是說,在運行多個測試用例和測試方法時,Spring容器僅需要實例化一次就可以了,極大地提高了基于Spring容器測試程序的運行效率。Spring通過這個測試幫助類解決了前面我們所指出的第1)個問題。
AbstractSingleSpringContextTests
AbstractSingleSpringContextTests繼承于AbstractSpringContextTests,它通過一些方法讓你方便地指定Spring配置文件所在位置:
String[] getConfigLocations():該方法允許你在指定Spring配置文件時使用資源類型前綴,這些資源類型前綴包括:classpath:、file:。以類似于“com/baobaotao/beans.xml”形式指定的資源被當成類路徑資源處理;
String[] getConfigPaths():以“/”開頭的地址被當成類路徑處理,如“/com/baobaotao/beans.xml”,而未以“/”開頭的地址被當成相對于測試類所在包的文件路徑,如“beans.xml”表示配置文件在測試類所在類包的目錄下;
String getConfigPath():和getConfigPaths()類似,在僅需指定一個配置文件中使用。
以上三個方法,它們的優先級和我們介紹的先后順序對應,也就是說,當你在子類中覆蓋了getConfigLocations()方法后,其它兩個方法就沒有意義了。所以你僅需選擇三者當中適合的方法進行覆蓋,而沒有必要同時覆蓋多個方法。
AbstractSingleSpringContextTests將根據這些方法指定的Spring配置文件初始化Spring容器,然后將Spring容器引用添加到static緩存中。并通過getApplicationContext()向子類開放ApplicationContext的引用。
一般情況下,所有的測試類和測試方法都可以共享這個Spring容器直到測試完結,不過在某些極端情況下,測試方法可能會對Spring容器進行改動(比如通過程序改變Bean的配置定義),如果這種改變對于其它測試方法來說是有干擾的,這就相當于“弄臟”了作為測試現場的Spring容器,因此在下一個測試方法執行前必須“抹除”這個改變。你可以簡單地在會“弄臟”Spring容器的測試方法中添加setDirty()方法向AbstractSingleSpringContextTests報告這一行為,這樣在下一個測試方法執行前,AbstractSingleSpringContextTests就會重新加載Spring容器以修補被“弄臟”的部分。
雖然你可以直接繼承AbstractSpringContextTests或AbstractSingleSpringContextTests創建自己的集成測試用例,不過你大可不必如此著急。Spring已經提供了幾個功能齊全、實踐性更強的子類,讓我們繼續探索Spring集成測試工具類的精彩篇章吧。
原文轉自:http://www.anti-gravitydesign.com