重要的是要認識到委派邏輯的優缺點,用 mock 進行測試對于使用對象或方面的技術都是類似的。在這兩種情況下,都是分離關注點,然后以更隔離的方法驗證每一個關注點。
對于注入 mock 來說,有一個特定于方面的問題。如果使用單元素方面(默認的),那么對于方面的字段所做的所有改變,如用 mock 替換一個字段,在測試結束時都必須撤銷。(否則,mock 會掛起并可能影響系統的其他部分。)這種銷毀邏輯很難實現和記憶。編寫一個測試清理方面,自動在每次測試后像在例子中那樣重新設置方面從概念上來說是簡單的,但是其細節超出了本文的范圍。
IV. 使用 mock 目標
在最后一節中,我介紹了我自己發明的、用于描述在編寫方面測試時用到的一種測試 helper 類類型的術語:mock 目標。在方面之前的世界中,一個 mock 對象 表示一個(手寫或者動態生成)的類,它模仿要測試的一些類的協作器。與此類似,mock 目標 是一個模仿要測試的一些方面的合法建議目標的類。
為了創建 mock 目標,編寫一個與生產中的建議有某些相似結構或者行為的類。例如,如果對于由 getter 返回的文字的突出顯示感興趣,可以編寫下面這樣的一個 mock 目標:
//an inner class of the enclosing test case
public class HighlightMockTarget implements Highlightable {
public String getSomeString() {
return "I am a big bear!";
}
}
然后,編寫測試用例以驗證方面正確地與目標交互,如清單 4 所示:
清單 4. 與 mock 目標交互以測試建議
public void setUp() throws Exception {
super.setUp();
setUpMockHighlightUtil();
words = Collections.singleton("big");
mockTarget = new HighlightMockTarget();
mockTarget.setHighlightedWords(words);
}
//mock setup/tearDown omitted
public void testHighlighting() {
mockUtil.expects(once())
.method("highlight")
.with(eq("I am a big bear!"), eq(words))
.will(returnValue("highlighted text"));
String shouldBeHighlighted = mockTarget.getSomeString();
assertEquals(shouldBeHighlighted, "highlighted text");
}
注意在這個例子中,我結合了 mock 目標和 mock 對象。mock 目標為下面三種技術提供了基礎。
模式 1. 通過擴展一個抽象方面并提供一個切點來測試建議
針對 :橫切功能
概述 :Prework :如果有必要,重新編寫方面,將它分為一個抽象方面以及一個擴展它并具體化一個或者多個切點的具體方面。
有了抽象方面后,在測試類中創建一個 mock 目標。創建一個擴展了抽象方面的測試方面。讓測試方面提供明確針對 mock 目標的切點。這個測試通過查找建議的已知副作用或者使用一個 mock 對象來驗證方面中的建議是否成功。
示例:擴展 AbstractHighlighter
文章來源于領測軟件測試網 http://www.kjueaiud.com/