Highlighter 方面捕獲聯(lián)結(jié)點(diǎn)的返回值并換成突出顯示的版本。它根據(jù)存儲(chǔ) 在 Highlightable 接口中一個(gè)類(lèi)型間字段中的突出顯示術(shù)語(yǔ)清單選擇要突出顯示的 術(shù)語(yǔ)?梢詫(duì)任何需要表現(xiàn)突出顯示行為的類(lèi)使用 Highlightable 接口,既可 以 使用在類(lèi)聲明中,也可以使用 declare parents 語(yǔ)句。
在這個(gè)例子的初始版本中,我選用一個(gè)非常簡(jiǎn)單的切點(diǎn)。在本文的后面,我 將 重寫(xiě)這個(gè)切點(diǎn)以展示一些測(cè)試模式。
I. 測(cè)試集成的單元
針對(duì) :橫切功能和規(guī)范
概述 :如在介紹中說(shuō)明的,使用方面很容易進(jìn)行集成測(cè)試。這個(gè)模式非常簡(jiǎn) 單:像行為沒(méi)有實(shí)現(xiàn)方面那樣為系統(tǒng)編寫(xiě)一個(gè)測(cè)試。換句話(huà)說(shuō),將對(duì)象放到一 起、設(shè)置狀態(tài)、調(diào)用方法,然后驗(yàn)證結(jié)果。關(guān)鍵是編寫(xiě)一個(gè)當(dāng)方面行為錯(cuò)誤或者 沒(méi)有應(yīng)用到希望它應(yīng)用的聯(lián)結(jié)點(diǎn)處時(shí)會(huì)失敗的測(cè)試。如果方面會(huì)影響多個(gè)聯(lián)結(jié)點(diǎn) ,那么選擇幾個(gè)代表例子。
例子:Highlighter 的集成測(cè)試
在清單 2 中要注意的是,這個(gè)測(cè)試的操作像對(duì)沒(méi)有使用方面的應(yīng)用程序一 樣。它將對(duì)象放到一樣、設(shè)置狀態(tài)、調(diào)用方法并驗(yàn)證結(jié)果。
清單 2. 對(duì) Highlighter 的集成測(cè)試
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());
}
}
優(yōu)缺點(diǎn)
不管是否使用 AOP,集成測(cè)試的代價(jià)和優(yōu)點(diǎn)是類(lèi)似的。不管哪種情況,主要 的 好處是驗(yàn)證代碼的高層目標(biāo)(換句話(huà)說(shuō),正確突出顯示標(biāo)題和結(jié)束語(yǔ))。在進(jìn)行 大的重構(gòu)時(shí)它會(huì)提供幫助。它還會(huì)找出當(dāng)組件交互時(shí)才會(huì)出現(xiàn)的問(wèn)題。
不過(guò),只進(jìn)行集成測(cè)試會(huì)帶來(lái)一些問(wèn)題。如果 HighlightSearchResultsIntegrationTest 失敗,那么這可能是因?yàn)榻ㄗh邏輯或 者所涉及的其他類(lèi)(如 SearchResult)有錯(cuò)誤,而使方面根本沒(méi)有運(yùn)行。事實(shí) 上 ,我在開(kāi)發(fā)這個(gè)集成測(cè)試?yán)訒r(shí)遇到了這種情況。我花了 20 分鐘試圖搞清楚 為什么方面沒(méi)有運(yùn)行,后發(fā)現(xiàn)在正則表達(dá)式中有一個(gè)暗藏的問(wèn)題!
集成測(cè)試還需要更復(fù)雜的設(shè)置和斷言,這使它們比分別測(cè)試單獨(dú)的方面更難 編 寫(xiě)。并且很難用集成測(cè)試模擬代碼需要正確處理的所有臨界情況。
橫切數(shù)個(gè)類(lèi)的行為給集成測(cè)試帶來(lái)了一個(gè)特定問(wèn)題。假定對(duì)應(yīng)用程序中的所 有 類(lèi)有統(tǒng)一的異常處理。我們不想對(duì)每一個(gè)類(lèi)測(cè)試這個(gè)新行為。相反,希望選擇一 個(gè)代表性的例子。但是如果選擇了特定的 域類(lèi)(比如 Customer 類(lèi)),并測(cè)試 了 它的錯(cuò)誤處理方面,那么會(huì)有模糊測(cè)試目的的可能性。測(cè)試是驗(yàn)證 Customer 的行為還是驗(yàn)證應(yīng)用程序的錯(cuò)誤處理呢?
II. 使用可視化工具
關(guān)于測(cè)試廣泛分布的橫切關(guān)注點(diǎn)的一個(gè)難題是它會(huì)報(bào)告太多的聯(lián)結(jié)點(diǎn)。執(zhí)行 并 檢查所有的匹配是個(gè)大麻煩。(另一方面,意外加入不需要的聯(lián)結(jié)點(diǎn)會(huì)更糟糕) 。相應(yīng)地,下面兩個(gè)模式展現(xiàn)了使用在 AJDT 這樣的工具中提供的人工檢測(cè)橫切 視圖補(bǔ)充正常測(cè)試的好處。(在撰寫(xiě)本文時(shí),AspectJ 與 AJDT 結(jié)合提供了大多 數(shù)可視化支持,不過(guò),JBoss AOP 和 JBoss IDE 等其他組合同樣提供了很好的 可 視化工具。)
模式 1. 可視化地檢查橫切
針對(duì) :橫切規(guī)范
概述 :在開(kāi)發(fā)方面時(shí)使用 AJDT 的 cross-references 視圖查看它要建議哪 些聯(lián)結(jié)點(diǎn)。人工驗(yàn)證清單是否完整,并且不包含應(yīng)忽略的聯(lián)結(jié)點(diǎn)。
例子:找出不需要的匹配
假定要突出顯示標(biāo)題、產(chǎn)品和搜索結(jié)果的匯總。不用像在 清單 1 中那樣枚 舉 每一個(gè)方法,可以說(shuō)明想要找的是一個(gè)更健壯的切點(diǎn)。(關(guān)于健壯的切點(diǎn)的更多 內(nèi)容,請(qǐng)參閱 參考資料 中 Adrian Colyer 的 blog。)下面的切點(diǎn)看來(lái)是抓住 了原來(lái)的想法:
public pointcut highlightedTextProperties() :
(
execution(public String get*())
&& ! execution(public * Highlightable.*(..))
);
不過(guò),在用 AJDT 的 cross-references 視圖檢查切點(diǎn)時(shí),會(huì)看到圖 2 所示 的內(nèi)容:
圖 2. AJDT cross-references 視圖中四個(gè)建議的聯(lián)結(jié)點(diǎn)
注意有一個(gè)多余的匹配:SearchResult.getWebsite()。您知道這個(gè) Website 不應(yīng)該突出顯示,因此重新編寫(xiě)這個(gè)切點(diǎn)以排除不需要的匹配。