<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 56, comments - 77, trackbacks - 0, articles - 1
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    假冒的藝術

    Posted on 2008-07-07 22:14 切爾斯基 閱讀(2095) 評論(1)  編輯  收藏

    預處理的接入點

    • 構建腳本中的宏定義可以控制將文本解釋為真正的實現還是假的實現

    • 構建腳本中的頭文件搜索路徑可被用來控制接入真正的聲明還是假的聲明

    • 頭文件中的防衛宏可被用來接入假的聲明以遮擋真正的聲明被包含進來

    上面第二點通常要求提供同名的頭文件, 而使用不同的構建設置

    而第三點不要求同名, 只要使用相同的防衛宏, 并保證把包含替代聲明的頭文件放在真正的頭文件前面包含進來就可以, 使用同一構建設置即可

    編譯鏈接的接入點

    • 構建腳本中的庫搜索路徑可被用來控制接入真正的實現還是假的實現

    • 針對接口編程, 可以控制接入真正的實現還是假的實現

    • 與針對接口編程類似, 使用函數指針/函數對象等封裝函數, 可以接入假的實現

    • 使用函數封裝數據訪問, static訪問, new 操作符, 可以子類化以接入假的實現

    • 改造為模板, 可以傳入不同的模板實參來控制接入真正的實現還是假的實現

    • 利用名稱作用范圍, 同名局部變量可遮擋其它名字等, 來控制接入真正的實現還是假的實現

    • 利用對象的內存布局, 直接將某幾個假的函數地址組成的 vtable, 強轉為被測類型

    運行時的接入點

    • 解釋型動態語言, 直接在測試前重定義

    • 編譯型靜態語言, 運行時修改函數地址

    基本上兩個原則

    • 尋找, 引入, 利用一切可能的接入點

    • 在一切依賴具體實現的地方, 插入一層間接

    例子: 測試使用了 static 函數, new 操作符的客戶代碼

    在 TDD 流行之后, 關于 Singleton, static 函數, new 操作符等依賴具體實現的代碼被推薦避免使用. 遺留系統中則不可避免的保留著. 它們被批評的原因是使它們的客戶代碼難以測試. 我們可以利用 "使用函數封裝數據訪問, static訪問, new 操作符, 可以子類化以接入假的實現" 來進行測試.

    public class SingletonClient {

     publicvoid doSomething(){

        SingletonObject service = SingletonObject.instance();

        service.execute();

      }

    }

    上面的這個SingletonClient的doSomething是無法測試的, 因為引用了一個靜態函數. 可以把對靜態函數的引用抽取到一個可覆寫的函數中來引入接入點:

    class SingletonClient {

      publicvoid doSomething(){

        SingletonObject service = getServiceObject();

        service.execute();

      }

      protected SingletonObject getServiceObject() {

        return SingletonObject.instance();

      }

    }

    這樣測試時我們便可以子類化SingletonClient, 只重寫getServiceObject, 便可以針對這個子類進行測試, 效果與針對基類測試是一樣的(因為其它的函數實現都相同, 只是依賴的第三方對象被替換為了假的實現):

    class SingletonClientInTestEnvironment extends SingletonClient {

      protected SingletonObject getServiceObject() {

        returnnew SingletonObjectStub();

      }

    }

    例子: C++ 測試, 用遮蓋技術(定義同名服務類), 當同時需要測真正的服務類本身時如何解決鏈接問題? (重定義)

    那就不要定義同名的類, #define 一個宏加一層間接, 恰當的時候 #undef. 如果是函數, 可以定義一個函數對象來封裝想假冒的函數, 生成該函數對象類型的一個變量時, 使用與函數相同的名字, 利用名字的作用域規則來遮蓋原來的函數.



    評論

    # re: 假冒的藝術  回復  更多評論   

    2013-02-28 10:33 by 王鵬飛
    哦,測試與開發的融合

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲中文字幕在线乱码| 天天干在线免费视频| 中文字幕在线亚洲精品| 人人爽人人爽人人片av免费| 免费一看一级毛片全播放| 国产偷国产偷亚洲高清在线| 国产三级免费电影| 国产免费高清69式视频在线观看| 亚洲亚洲人成综合网络| 男人都懂www深夜免费网站| 久久亚洲私人国产精品vA| 亚欧免费视频一区二区三区| 亚洲的天堂av无码| 成年人性生活免费视频| 精品亚洲成a人在线观看| 亚洲国产成人五月综合网| 香蕉免费看一区二区三区| 亚洲人成网址在线观看 | 亚洲国产成人片在线观看无码 | 亚洲一级毛片中文字幕| 女人18毛片免费观看| 亚洲成AV人影片在线观看| 亚洲人成无码网WWW| 午夜无码A级毛片免费视频 | 国产成人无码精品久久久免费| 亚洲人成网亚洲欧洲无码久久| 久久久久国产精品免费免费不卡| 亚洲无圣光一区二区| 日韩电影免费在线| 两个人看的www高清免费视频| 亚洲欧洲自拍拍偷午夜色| 日韩一级视频免费观看| a毛片免费播放全部完整| 国产精品亚洲四区在线观看 | 亚洲AV无码成人网站在线观看| 亚洲精品456播放| 午夜免费1000部| 一级午夜a毛片免费视频| 亚洲毛片免费视频| 亚洲成片观看四虎永久| 最近中文字幕免费mv在线视频|