• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    用模仿對象替換合作者以改進單元測試

    發布: 2008-7-30 09:55 | 作者: Alexander Day Chaffe | 來源: IBM | 查看: 71次 | 進入軟件測試論壇討論

    領測軟件測試網

    重構由許多小的技術性步驟組成。這些步驟統稱為 技巧。如果您象按照食譜那樣嚴格遵循這些技術, 那么您在學習重構時應該沒有太大的麻煩。

    1. 標識創建或獲取合作者的代碼的所有出現。
    2. 抽取方法重構應用于這個創建代碼,創建工廠方法(在 Fowler 書籍的第 110 頁中討論;有關更多信息,請參閱 參考資料一節)。
    3. 確保目標對象及其子類可以訪問工廠方法。(在 Java 語言中,使用 protected 關鍵字)。
    4. 在測試代碼中,創建模仿對象且實現與合作者相同的接口。
    5. 在測試代碼中,創建擴展(專用于)目標對象的特殊化對象。
    6. 在特殊化對象中,覆蓋創建方法以返回為測試提供的模仿對象。
    7. 可選的:創建單元測試以確保原始目標對象的工廠方法仍返回正確的非模仿對象。

    示例:ATM

    設想您正在編寫用于銀行自動柜員機(Automatic Teller Machine)的測試。其中一個測試可能類似于清單 2:


    清單 2. 初始單元測試,在模仿對象引入之前
     public void testCheckingWithdrawal() {
    float startingBalance = balanceForTestCheckingAccount();
    AtmGui atm = new AtmGui();
    insertCardAndInputPin(atm);
    atm.pressButton("Withdraw");
    atm.pressButton("Checking");
    atm.pressButtons("1", "0", "0", "0", "0");
    assertContains("$100.00", atm.getDisplayContents());
    atm.pressButton("Continue");
    assertEquals(startingBalance - 100,
    balanceForTestCheckingAccount());
    }

    另外, AtmGui 類內部的匹配代碼可能類似于清單 3:


    清單 3. 產品代碼,在重構之前
     private Status doWithdrawal(Account account, float amount) {
    Transaction transaction = new Transaction();
    transaction.setSourceAccount(account);
    transaction.setDestAccount(myCashAccount());
    transaction.setAmount(amount);
    transaction.process();
    if (transaction.successful()) {
    dispense(amount);
    }
    return transaction.getStatus();
    }

    該方法將起作用,遺憾的是,它有一個副作用:支票帳戶余額比測試開始時少,這使得其它測試變得更困難。 有一些解決這種困難的方法,但它們都會增加測試的復雜性。 更糟的是,該方法還需要對管理貨幣的系統進行三次往返。

    要修正這個問題,第一步是重構 AtmGui 以允許我們用模仿事務替換實際事務, 如清單 4 中所示(比較 粗體的源代碼以查看我們正在更改什么):


    清單 4. 重構 AtmGui
     private Status doWithdrawal(Account account, float amount) {
    Transaction transaction = createTransaction();
    transaction.setSourceAccount(account);
    transaction.setDestAccount(myCashAccount());
    transaction.setAmount(amount);
    transaction.process();
    if (transaction.successful()) {
    dispense(amount);
    }
    return transaction.getStatus();
    }
    protected Transaction createTransaction() {
    return new Transaction();
    }

    后退到測試類內部,我們將 MockTransaction 類定義為成員類,如清單 5 中所示:


    清單 5. 將 MockTransaction 定義為成員類
     private MockTransaction extends Transaction {
    private boolean processCalled = false;
    // override process method so that no real work is done
    public void process() {
    processCalled = true;
    setStatus(Status.SUCCESS);
    }
    public void validate() {
    assertTrue(processCalled);
    }
    }

    最后,我們可以重寫測試,以便被測試的對象使用 MockTransaction 類,而不是使用實際類,如清單 6 中所示:


    文章來源于領測軟件測試網 http://www.kjueaiud.com/

    32/3<123>

    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>