Alexander Day Chaffee(alex@jguru.com),顧問,Purple Technology William Pietri(william@scissor.com),顧問,Scissor
模擬對象(Mock object)是為起中介者作用的對象編寫單元測試的有用方法。測試對象調用模擬域對象(它只斷言以正確的次序用期望的參數調用了正確的方法),而不是調用實際域對象。然而,當測試對象必須創建域對象時,我們面臨一個問題。測試對象如何知道創建模擬域對象,而不是創建實際域對象呢?在本文中,軟件顧問 Alexander Day Chaffee 和 William Pietri 將演示一種重構技術,該技術根據工廠方法設計模式來創建模擬對象。 單元測試已作為軟件開發的“最佳實踐”被普遍接受。當編寫對象時,還必須提供一個自動化測試類,該類包含測試該對象性能的方法、用各種參數調用其各種公用(public)方法并確保返回值是正確的。
在 Nicholas Lesiecki 的文章“Test flexibly with aspectJ and mock objects”中,他指出重構不一定總是合意的,也不一定總是產生更清楚或更輕易理解的代碼。在許多情況下,更改方法簽名以使合作者成為參數將會在方法的原始調用者內部產生混淆的、未經試驗的代碼混亂。
許多語言對于“工廠”這一概念都附有一些約定,它們會使您誤入歧途。例如,在 Java 語言中,工廠通常作為靜態方法實現;在這種情況下,這是不合適的。 請記住,本練習的宗旨是使對象更易于測試。通常,用于可測性的設計可以將對象的 API 推向一種更清楚更模塊化的狀態。但它會走得太遠。測試驅動的設計更改不應該污染原始對象的公用接口。
在 ATM 示例中,對于產品代碼,AtmGui 對象始終只產生一種類型的 Transaction 對象(實際類型)。測試代碼希望它產生另一種類型的對象(模擬對象)。但強迫公用 API 適應工廠對象或抽象工廠(只因為測試代碼要求它這樣)是錯誤的設計。假如產品代碼無需實例化該合作者的多個類型,那么添加該功能將使最終的設計不必要地變得難于理解。
參考資料
由 Tim Mackinnon、Steve Freeman 和 Philip Craig 合著的文章“Endo-Testing: Unit Testing with Mock Objects”介紹了術語模擬對象。
Mock Objects Project 是支持模擬對象實現的框架。
工廠方法和抽象工廠設計模式的來源是由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides(也稱為四人組(Gang of Four))合著的 Design Patterns: Elements of Reusable Object-Oriented Software(Addison-Wesley,1997 年)。
William Pietri 的父親是一位系統分析師和企業家,William 在十三歲時就開始利用計算機賺取午餐費。從那以后,他幾乎從事過技術領域的各個方面,從技術支持到系統治理到軟件工程到用戶界面設計。他是 Scissor(技術咨詢公司)的創辦人。可以通過 william@scissor.com 與 William 聯系。