Highlighter 方面捕獲聯結點的返回值并換成突出顯示的版本。它根據存儲 在 Highlightable 接口中一個類型間字段中的突出顯示術語清單選擇要突出顯示的 術語。可以對任何需要表現突出顯示行為的類使用 Highlightable 接口,既可 以 使用在類聲明中,也可以使用 declare parents 語句。
在這個例子的初始版本中,我選用一個非常簡單的切點。在本文的后面,我 將 重寫這個切點以展示一些測試模式。
I. 測試集成的單元
針對 :橫切功能和規范
概述 :如在介紹中說明的,使用方面很容易進行集成測試。這個模式非常簡 單:像行為沒有實現方面那樣為系統編寫一個測試。換句話說,將對象放到一 起、設置狀態、調用方法,然后驗證結果。關鍵是編寫一個當方面行為錯誤或者 沒有應用到希望它應用的聯結點處時會失敗的測試。如果方面會影響多個聯結點 ,那么選擇幾個代表例子。
例子:Highlighter 的集成測試
在清單 2 中要注意的是,這個測試的操作像對沒有使用方面的應用程序一 樣。它將對象放到一樣、設置狀態、調用方法并驗證結果。
清單 2. 對 Highlighter 的集成測試
public class HighlightSearchResultsIntegrationTest extends TestCase {
Collection words;
private SearchResult result;
public void setUp() throws Exception {
super.setUp();
words = new ArrayList();
words.add("big");
words.add("grrr");
result = new SearchResult();
result.setTitle("I am a big bear!");
result.setSummary("grrr growl!");
result.setHighlightedWords (words);
}
public void testHighlighting() {
String expected = "I am a big bear!";
assertEquals(expected, result.getTitle());
expected = "grrr growl!";
assertEquals(expected, result.getSummary());
}
}
優缺點
不管是否使用 AOP,集成測試的代價和優點是類似的。不管哪種情況,主要 的 好處是驗證代碼的高層目標(換句話說,正確突出顯示標題和結束語)。在進行 大的重構時它會提供幫助。它還會找出當組件交互時才會出現的問題。
不過,只進行集成測試會帶來一些問題。如果 HighlightSearchResultsIntegrationTest 失敗,那么這可能是因為建議邏輯或 者所涉及的其他類(如 SearchResult)有錯誤,而使方面根本沒有運行。事實 上 ,我在開發這個集成測試例子時遇到了這種情況。我花了 20 分鐘試圖搞清楚 為什么方面沒有運行,后發現在正則表達式中有一個暗藏的問題!
集成測試還需要更復雜的設置和斷言,這使它們比分別測試單獨的方面更難 編 寫。并且很難用集成測試模擬代碼需要正確處理的所有臨界情況。
橫切數個類的行為給集成測試帶來了一個特定問題。假定對應用程序中的所 有 類有統一的異常處理。我們不想對每一個類測試這個新行為。相反,希望選擇一 個代表性的例子。但是如果選擇了特定的 域類(比如 Customer 類),并測試 了 它的錯誤處理方面,那么會有模糊測試目的的可能性。測試是驗證 Customer 的行為還是驗證應用程序的錯誤處理呢?
II. 使用可視化工具
關于測試廣泛分布的橫切關注點的一個難題是它會報告太多的聯結點。執行 并 檢查所有的匹配是個大麻煩。(另一方面,意外加入不需要的聯結點會更糟糕) 。相應地,下面兩個模式展現了使用在 AJDT 這樣的工具中提供的人工檢測橫切 視圖補充正常測試的好處。(在撰寫本文時,AspectJ 與 AJDT 結合提供了大多 數可視化支持,不過,JBoss AOP 和 JBoss IDE 等其他組合同樣提供了很好的 可 視化工具。)
模式 1. 可視化地檢查橫切
針對 :橫切規范
概述 :在開發方面時使用 AJDT 的 cross-references 視圖查看它要建議哪 些聯結點。人工驗證清單是否完整,并且不包含應忽略的聯結點。
例子:找出不需要的匹配
假定要突出顯示標題、產品和搜索結果的匯總。不用像在 清單 1 中那樣枚 舉 每一個方法,可以說明想要找的是一個更健壯的切點。(關于健壯的切點的更多 內容,請參閱 參考資料 中 Adrian Colyer 的 blog。)下面的切點看來是抓住 了原來的想法:
public pointcut highlightedTextProperties() :
(
execution(public String get*())
&& ! execution(public * Highlightable.*(..))
);
不過,在用 AJDT 的 cross-references 視圖檢查切點時,會看到圖 2 所示 的內容:
圖 2. AJDT cross-references 視圖中四個建議的聯結點
注意有一個多余的匹配:SearchResult.getWebsite()。您知道這個 Website 不應該突出顯示,因此重新編寫這個切點以排除不需要的匹配。