小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

使用 SDAO 進(jìn)行 J2EE 測(cè)試的分步方法

 思奇劍 2006-11-16
使用模擬和實(shí)際數(shù)據(jù)訪問(wèn)對(duì)象來(lái)有效而又高效地測(cè)試 J2EE 應(yīng)用程序

 

數(shù)據(jù)訪問(wèn)對(duì)象(Data Access Object)模式已經(jīng)成為 J2EE 開(kāi)發(fā)人員工具庫(kù)中的標(biāo)準(zhǔn)部件。大多數(shù)開(kāi)發(fā)人員不知道它有一個(gè)變體可以使測(cè)試更輕松。 模擬數(shù)據(jù)訪問(wèn)對(duì)象集中了 DAO、模仿對(duì)象和分層測(cè)試的精華,從而允許您同時(shí)改進(jìn)測(cè)試結(jié)果和整體開(kāi)發(fā)方法。企業(yè) Java 開(kāi)發(fā)人員(并且是 SDAO 大師)Kyle Brown 使用代碼樣本和討論向您全面介紹 SDAO 的概念和日常用法。

今年早些時(shí)候,我在北卡羅萊納州立大學(xué)(North Carolina State University)給一群研究生作了一個(gè)關(guān)于 J2EE 技術(shù)的演講。我提供了一個(gè)說(shuō)明 servlet 和 JSP 用法的樣本設(shè)計(jì),以說(shuō)明如何結(jié)合 MVC 方法和簡(jiǎn)單數(shù)據(jù)訪問(wèn)對(duì)象(DAO)以處理應(yīng)用程序中持久數(shù)據(jù)的查詢和更新。在陳述這些材料時(shí),我看到聽(tīng)眾們會(huì)心地微笑和點(diǎn)頭。但是,在陳述結(jié)束之后,我收到了一個(gè)學(xué)生的電子郵件。為什么我實(shí)現(xiàn)的 DAO 不止一個(gè),而是兩個(gè),又為什么設(shè)置了一個(gè) Factory 類以允許在它們之間進(jìn)行選擇呢?

這很令人費(fèi)解,但是我很快意識(shí)到了問(wèn)題所在:我忘了告訴那些學(xué)生,我正在實(shí)現(xiàn) MVC 和 DAO 之外的第三種模式。尤其是,我的設(shè)計(jì)利用了模仿對(duì)象來(lái)簡(jiǎn)化測(cè)試。在我考慮 DAO 的方式中,模仿對(duì)象是很基本的,以致我無(wú)法想象在缺少其中一個(gè)的情況下如何實(shí)現(xiàn)另一個(gè)。進(jìn)一步說(shuō),我自動(dòng)地調(diào)整了設(shè)計(jì),以便使測(cè)試更容易,這對(duì)許多經(jīng)驗(yàn)豐富的開(kāi)發(fā)人員和我的學(xué)生們都是一個(gè)同樣陌生的概念。

在本文中,您將了解使用模擬數(shù)據(jù)訪問(wèn)對(duì)象(SDAO)進(jìn)行分層測(cè)試。與模仿對(duì)象一樣,SDAO 用專門為測(cè)試開(kāi)發(fā)的對(duì)象取代現(xiàn)有對(duì)象。但是,與模仿對(duì)象不同的是,不需要對(duì) SDAO 提供檢測(cè)以包含測(cè)試斷言。SDAO 模式的目的是允許您將一個(gè)層(域?qū)ο髮樱┖土硪粋€(gè)層(數(shù)據(jù)訪問(wèn)層)隔離開(kāi)。我們將從回顧數(shù)據(jù)訪問(wèn)對(duì)象模式入手。

關(guān)于模式的只言片語(yǔ)
閱讀更多有關(guān)模式如何向開(kāi)發(fā)人員提供共享設(shè)計(jì)詞匯表的內(nèi)容。

數(shù)據(jù)訪問(wèn)對(duì)象
數(shù)據(jù)訪問(wèn)對(duì)象模式的目的是提供到特定數(shù)據(jù)源的單個(gè)聯(lián)系點(diǎn)。與許多設(shè)計(jì)模式相似,DAO 以分隔設(shè)計(jì)任務(wù)為基礎(chǔ)。具體來(lái)說(shuō),DAO 將業(yè)務(wù)邏輯與數(shù)據(jù)庫(kù)持久性代碼分隔開(kāi)來(lái)。數(shù)據(jù)訪問(wèn)對(duì)象負(fù)責(zé)對(duì)持有數(shù)據(jù)(存儲(chǔ)在關(guān)系數(shù)據(jù)庫(kù)中)的對(duì)象進(jìn)行操作。DAO 所操作的對(duì)象通常稱為 值對(duì)象,盡管術(shù)語(yǔ) 數(shù)據(jù)傳送對(duì)象(data transfer object,DTO)的意思更為貼切。

DAO 類通常包含對(duì)其 DTO 進(jìn)行操作的 CRUD 方法,即 create() 、 read() 、 update()delete() 。例如,假定我們正在構(gòu)建一個(gè)登記會(huì)議出席人員的系統(tǒng)。我們的 DAO 類接口可能如清單 1 中所示:

清單 1. 示例 DAO 類接口
public interface AttendeeDAO {
            public void createAttendee(Attendee person) throws DAOException;
            public void updateAttendee(Attendee person) throws DAOException;
            public Collection getAllAttendees() throws DAOException;
            public void deleteAttendee(Attendee person) throws DAOException;
            public Attendee findAttendeeForPrimaryKey(int primaryKey)
            throws DAOException;
            

聲明這個(gè)接口(或與它類似的接口)是實(shí)現(xiàn) DAO 模式的標(biāo)準(zhǔn)部分。具體的 DAO 應(yīng)用程序?qū)?shí)現(xiàn)如圖 1 中所示的接口:

圖 1. 示例 DAO 應(yīng)用程序
示例 DAO 應(yīng)用程序的圖

消息處理
在大多數(shù)情況下,類似于上述示例的 DAO 應(yīng)用程序會(huì)使用 JDBC 進(jìn)行數(shù)據(jù)庫(kù)訪問(wèn)。例如,在 getAllAttendees() 方法的示例中,該類將獲取一個(gè)到數(shù)據(jù)庫(kù)的連接,查詢數(shù)據(jù)庫(kù)以獲取 Attendee 表中的行列表,迭代從查詢返回的 ResultSet ,然后為 ResultSet 中每一行構(gòu)造 Attendee 對(duì)象。

請(qǐng)參閱 參考資料以獲取 DAO 模式的深入討論和示例。

模擬數(shù)據(jù)訪問(wèn)對(duì)象
模擬數(shù)據(jù)訪問(wèn)對(duì)象實(shí)際上模擬后端數(shù)據(jù)存儲(chǔ)。實(shí)現(xiàn) SDAO 模式使我們能夠測(cè)試各種應(yīng)用程序?qū)樱ㄈ鐦I(yè)務(wù)邏輯和 GUI),而無(wú)需恰好擁有實(shí)際的數(shù)據(jù)庫(kù)。

以下是使用 SDAO 進(jìn)行分層測(cè)試的一些具體優(yōu)點(diǎn):

  • 便宜:使用模擬數(shù)據(jù)庫(kù)進(jìn)行測(cè)試和調(diào)試使您節(jié)省了在每個(gè)開(kāi)發(fā)人員的桌面上安裝 DB2(比方說(shuō))的成本。
  • 容易:即使不必處理數(shù)據(jù)庫(kù)錯(cuò)誤,構(gòu)建具有 servlet、JSP 文件和 EJB 組件的應(yīng)用程序也夠復(fù)雜的了。分層測(cè)試允許您設(shè)計(jì)出表示和業(yè)務(wù)邏輯,而不必同時(shí)擔(dān)心后端數(shù)據(jù)庫(kù)。
  • 迅速:按層進(jìn)行分隔允許您在出現(xiàn)問(wèn)題時(shí)隔離它們,這使得調(diào)試周期更快。有些錯(cuò)誤(如 TransactionRollbackException )難以定位;從綜合體中除去數(shù)據(jù)庫(kù)層讓您更快地找出真實(shí)的問(wèn)題。
  • 靈活:SDAO 可以用于性能概要分析和測(cè)試。盡管有些類型的性能問(wèn)題(如數(shù)據(jù)庫(kù)死鎖)需要實(shí)際的數(shù)據(jù)庫(kù)來(lái)解決,但 SDAO 讓您獲得僅域和 GUI 性能的測(cè)量結(jié)果,然后可以利用這些結(jié)果來(lái)解決那些層上的問(wèn)題。

SDAO 實(shí)戰(zhàn)
理解 SDAO 如何工作的最佳方法是實(shí)際研究它,并希望您親自應(yīng)用它。我們將從模擬數(shù)據(jù)訪問(wèn)對(duì)象的簡(jiǎn)單示例入手,如清單 2 所示:

清單 2. DefaultDAO
public class DefaultDAO implements AttendeeDAO {
            private static DefaultDAO instance = new DefaultDAO();
            private Vector attendees = new Vector();
            /**
            * @see AttendeeDAO#createAttendee(Attendee)
            */
            public void createAttendee(Attendee person) throws DAOException {
            getAllAttendees().add(person);
            }
            /**
            * @see AttendeeDAO#updateAttendee(Attendee)
            */
            public void updateAttendee(Attendee person) throws DAOException {
            Attendee match =
            findAttendeeForPrimaryKey(person.getAttendeeKey());
            attendees.remove(match);
            attendees.add(person);
            }
            /**
            * @see AttendeeDAO#getAllAttendees()
            */
            public Collection getAllAttendees() throws DAOException {
            return getAttendees();
            }
            /**
            * @see AttendeeDAO#deleteAttendee(Attendee)
            */
            public void deleteAttendee(Attendee person) throws DAOException {
            Attendee match =
            findAttendeeForPrimaryKey(person.getAttendeeKey());
            attendees.remove(match);
            attendees.add(person);
            }
            /**
            * Gets the attendees
            * @return Returns a Vector
            */
            public Vector getAttendees() {
            return attendees;
            }
            /**
            * Sets the attendees
            * @param attendees The attendees to set
            */
            public void setAttendees(Vector attendees) {
            this.attendees = attendees;
            }
            /**
            * Gets the instance
            * @return Returns a DefaultDAO
            */
            public static DefaultDAO getInstance() {
            return instance;
            }
            /**
            * Sets the instance
            * @param instance The instance to set
            */
            public static void setInstance(DefaultDAO anInstance) {
            instance = anInstance;
            }
            public Attendee findAttendeeForPrimaryKey(int primaryKey)
            throws DAOException {
            Enumeration enum = attendees.elements();
            while (enum.hasMoreElements()) {
            Attendee current = (Attendee) enum.nextElement();
            if (current.getAttendeeKey() == primaryKey)
            return current;
            }
            throw new DAOException("Primary Key not found "
            + primaryKey);
            }
            }
            

現(xiàn)在來(lái)看一下,這是晦澀的火箭科學(xué),是嗎? DefaultDAO 類在靜態(tài)變量 instance 中存儲(chǔ)了它自己的一個(gè)實(shí)例(存儲(chǔ)為 Singleton),并允許通過(guò) getInstance() 方法訪問(wèn)該實(shí)例。然后,該類的用戶可以在 Singleton 實(shí)例保存的集合中添加和刪除 Attendee 元素,或替換集合中的元素。

對(duì)象工廠
要使這種技術(shù)在實(shí)際工作中有效,需要能夠?qū)⒊绦蛑械?#8220;實(shí)際”DAO 類替換成新的“模擬”DAO 類。我們的客戶機(jī)代碼本身不能引用 Db2AttendeeDAO 類或 DefaultDAO 類。因此我們使用 Factory 類(又名對(duì)象工廠),以根據(jù)需要為客戶機(jī)代碼提供 Db2AttendeeDAODefaultDAO 實(shí)例。

我們的對(duì)象工廠相當(dāng)簡(jiǎn)單。它只返回兩個(gè)類實(shí)例,用一種軟件“開(kāi)關(guān)”(如 getAttendeeDAO() 方法中所示)在兩者之間進(jìn)行切換。這個(gè)開(kāi)關(guān)還可以檢查 System 特性的值,或檢查一些其它全局值,如清單 3 所示:

清單 3. AttendeeDAOFactory

            public class AttendeeDAOFactory {
            public static AttendeeDAO getAttendeeDAO() {
            String mode = (String) System.getProperty("TestMode");
            if (mode.equals("Simulated"))
            return DefaultDAO.getInstance();
            else
            return new DbAttendeeDAO();
            }
            }
            

當(dāng)您運(yùn)行測(cè)試時(shí),通常首先將 Factory 開(kāi)關(guān)設(shè)置成返回模擬類。這樣做確保您可以在與數(shù)據(jù)庫(kù)隔離的情況下測(cè)試系統(tǒng)的其余層。只有在后面的測(cè)試中才會(huì)將開(kāi)關(guān)設(shè)置成返回“實(shí)際”DAO。圖 2 使您對(duì)最終設(shè)計(jì)(包括 Factory 類)有一些了解,有可能如下所示:

圖 2. 示例 SDAO 實(shí)現(xiàn)
SDAO 實(shí)現(xiàn)圖

高級(jí) SDAO
在您理解了基本的 SDAO 實(shí)現(xiàn)之后,就可以研究其它使用模擬 DAO( DefaultDAO )類的方法。迄今為止,您所看到的只是最簡(jiǎn)單的實(shí)現(xiàn),其中的結(jié)果取自內(nèi)存中的集合,該集合在測(cè)試期間必須被填充。這種思想的常見(jiàn)擴(kuò)展是在類的構(gòu)造函數(shù)中預(yù)先用缺省值填充該集合。正如我們?cè)诖怂龅模褂?Singleton 的主要缺點(diǎn)是:您必須在各次測(cè)試之間清除 Singleton。如果您在某次測(cè)試時(shí)忘了這樣做,則會(huì)導(dǎo)致后面的測(cè)試失敗。幸運(yùn)的是,大多數(shù)單元測(cè)試框架(如 JUnit)提供了輕松進(jìn)行此類測(cè)試的工具。例如,在 JUnit 中,可以將清除 Singleton 的代碼放入測(cè)試類的 teardown() 方法中,并將任何執(zhí)行預(yù)先填充工作的代碼放到該測(cè)試類的 setUp() 方法中。

第二種方法略微復(fù)雜些,但也是為更實(shí)際的測(cè)試所提供的,這就是使用 Java 序列化或 XML 從文件讀取一組對(duì)象。這兩種技術(shù)都允許您使用幾個(gè)文件來(lái)表示同一個(gè)測(cè)試的不同初始條件。

我經(jīng)常在 SDAO 測(cè)試中使用“分兩步走”的方法。我構(gòu)建的第一個(gè) DAO 是“缺省”DAO;它轉(zhuǎn)至 DTO 內(nèi)存中集合,然后被傳遞給構(gòu)建應(yīng)用程序中上層部分(例如 servlet 和 JSP 文件)的團(tuán)隊(duì)。然后我和另一個(gè)團(tuán)隊(duì)一起構(gòu)建將實(shí)際使用數(shù)據(jù)庫(kù)的 DAO。這種方法允許兩個(gè)團(tuán)隊(duì)同時(shí)工作,他們的交互是由 DAO 接口的共享約定定義的。

結(jié)束語(yǔ)
在 IBM WebSphere 軟件服務(wù)組(Software Services for WebSphere group)中,我們已經(jīng)成功地將本文描述的分層測(cè)試技術(shù)應(yīng)用到了數(shù)十個(gè)客戶合作項(xiàng)目中。除了改進(jìn)我們的整個(gè)產(chǎn)品之外,SDAO 還成為了幫助我們團(tuán)隊(duì)掌握各種 J2EE API 特性的重要工具。使用模擬和實(shí)際 DAO 使我們可以在應(yīng)用程序的許多層上同時(shí)工作,而不會(huì)被一次性地將所有部分組裝到一起的復(fù)雜情況所“嚇倒”。

作者衷心地感謝 Stacy Joines 和 Ken Hygh 對(duì)本文提出的有益建議。

參考資料

  • 您可以參閱本文在 developerWorks 全球站點(diǎn)上的 英文原文.

  • 對(duì)設(shè)計(jì)模式感到好奇嗎?可以從“四人組(Gang of Four)”的 Design Patterns:Elements of Reusable Object Oriented Software (由 Erich Gamma、Richard Helms、Ralph Johnson 和 John Vlissides 合著;Addison-Wesley,1995 年)入手。

  • 除了 Design Patterns以外, Core J2EE Patterns:Best Practices and Design Strategies (由 Deepak Alur、John Crupi 和 Dan Malks 合著;Addison-Wesley,2001 年)也是 J2EE 開(kāi)發(fā)人員的必讀書(shū)籍。

  • Martin Fowler 的 Patterns of Enterprise Application Architecture (Addison-Wesley,2002 年)是企業(yè)開(kāi)發(fā)模式的另一本全面介紹。

  • 您也可能想查看 Paul Monday 的“ java 設(shè)計(jì)模式201”( developerWorks,2002 年 4 月),這是一篇適合于設(shè)計(jì)模式愛(ài)好者的高級(jí)教程。

  • Bruce Whitenack 和 Kyle Brown 共同編寫了 Crossing Chasms,這是一種用于關(guān)系數(shù)據(jù)庫(kù)和 smalltalk 的模式語(yǔ)言。您可以在 Kyle 的 主頁(yè)上了解其開(kāi)發(fā)(以及 Kyle 的其它項(xiàng)目)。

  • 通過(guò) Kyle Gabhart 的 J2EE 探索 系列( developerWorks)以了解更多關(guān)于本文簡(jiǎn)要提及的企業(yè)編程技術(shù)的信息。

  • Endo-Testing:Unit Testing with Mock Objects”(由 Tim Mackinnon、Steve Freeman 和 Philip Craig 合著;XP2000)是一篇有關(guān)單元測(cè)試和模仿對(duì)象的很棒的介紹 ― 并且它是第一篇關(guān)于這個(gè)主題的文章。

  • Sourceforge 目前保存著 Kent Beck 和 Erich Gamma 有關(guān)使用 JUnit 進(jìn)行單元測(cè)試的介紹,“ Test Infected:Programmers Love Writing Tests”( Java Report,1998 年 7 月)。

  • Alexander Day Chaffee 和 William Pietri 的“ 使用模仿對(duì)象進(jìn)行單元測(cè)試”( developerWorks,2002 年 11 月)向您展示了如何使用工廠模式來(lái)增強(qiáng)利用模仿對(duì)象的測(cè)試。

  • Malcolm Davis 的“ 利用 Ant 和 JUnit 進(jìn)行增量開(kāi)發(fā) ”( developerWorks,2000 年 11 月)讓您對(duì)單元測(cè)試有另一番了解,同時(shí)無(wú)形中又為您的工具箱增加了一種新技術(shù)。

  • 您可以將模仿對(duì)象測(cè)試與各種技巧和技術(shù)組合起來(lái)。Nicholas Lesiecki 的“ AspectJ 和模仿對(duì)象的測(cè)試靈活性”( developerWorks,2002 年 5 月)向您展示了模仿對(duì)象和面向方面(Aspect)的編程是如何一起工作的。

  • 您可以在 developerWorksJava 技術(shù)專區(qū) 中找到許多關(guān)于 Java 編程各方面的文章。

 

關(guān)于作者
Kyle Brown 是 IBM WebSphere 軟件服務(wù)部(Software Services for WebSphere)的高級(jí)技術(shù)組成員。Kyle 向財(cái)富 500 強(qiáng)客戶提供關(guān)于面向?qū)ο笾黝}和 Java 2 企業(yè)版(J2EE)技術(shù)的咨詢服務(wù)、培訓(xùn)和指導(dǎo)。他與別人合著了 Enterprise Java Programming with IBM WebSphere 、 WebSphere 4.0 AEs Workbook for Enterprise JavaBeans(第 3 版) The Design Patterns Smalltalk Companion 。他還經(jīng)常在研討會(huì)上發(fā)表關(guān)于企業(yè) Java、OO 設(shè)計(jì)和設(shè)計(jì)模式的演講。您可以通過(guò) mailto:brownkyl@us.ibm.com?subject=Stepped approach to J2EE testing with SDAO與他聯(lián)系。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多