<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 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    假冒的藝術(shù)

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

    預(yù)處理的接入點(diǎn)

    • 構(gòu)建腳本中的宏定義可以控制將文本解釋為真正的實(shí)現(xiàn)還是假的實(shí)現(xiàn)

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

    • 頭文件中的防衛(wèi)宏可被用來接入假的聲明以遮擋真正的聲明被包含進(jìn)來

    上面第二點(diǎn)通常要求提供同名的頭文件, 而使用不同的構(gòu)建設(shè)置

    而第三點(diǎn)不要求同名, 只要使用相同的防衛(wèi)宏, 并保證把包含替代聲明的頭文件放在真正的頭文件前面包含進(jìn)來就可以, 使用同一構(gòu)建設(shè)置即可

    編譯鏈接的接入點(diǎn)

    • 構(gòu)建腳本中的庫搜索路徑可被用來控制接入真正的實(shí)現(xiàn)還是假的實(shí)現(xiàn)

    • 針對(duì)接口編程, 可以控制接入真正的實(shí)現(xiàn)還是假的實(shí)現(xiàn)

    • 與針對(duì)接口編程類似, 使用函數(shù)指針/函數(shù)對(duì)象等封裝函數(shù), 可以接入假的實(shí)現(xiàn)

    • 使用函數(shù)封裝數(shù)據(jù)訪問, static訪問, new 操作符, 可以子類化以接入假的實(shí)現(xiàn)

    • 改造為模板, 可以傳入不同的模板實(shí)參來控制接入真正的實(shí)現(xiàn)還是假的實(shí)現(xiàn)

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

    • 利用對(duì)象的內(nèi)存布局, 直接將某幾個(gè)假的函數(shù)地址組成的 vtable, 強(qiáng)轉(zhuǎn)為被測(cè)類型

    運(yùn)行時(shí)的接入點(diǎn)

    • 解釋型動(dòng)態(tài)語言, 直接在測(cè)試前重定義

    • 編譯型靜態(tài)語言, 運(yùn)行時(shí)修改函數(shù)地址

    基本上兩個(gè)原則

    • 尋找, 引入, 利用一切可能的接入點(diǎn)

    • 在一切依賴具體實(shí)現(xiàn)的地方, 插入一層間接

    例子: 測(cè)試使用了 static 函數(shù), new 操作符的客戶代碼

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

    public class SingletonClient {

     publicvoid doSomething(){

        SingletonObject service = SingletonObject.instance();

        service.execute();

      }

    }

    上面的這個(gè)SingletonClient的doSomething是無法測(cè)試的, 因?yàn)橐昧艘粋€(gè)靜態(tài)函數(shù). 可以把對(duì)靜態(tài)函數(shù)的引用抽取到一個(gè)可覆寫的函數(shù)中來引入接入點(diǎn):

    class SingletonClient {

      publicvoid doSomething(){

        SingletonObject service = getServiceObject();

        service.execute();

      }

      protected SingletonObject getServiceObject() {

        return SingletonObject.instance();

      }

    }

    這樣測(cè)試時(shí)我們便可以子類化SingletonClient, 只重寫getServiceObject, 便可以針對(duì)這個(gè)子類進(jìn)行測(cè)試, 效果與針對(duì)基類測(cè)試是一樣的(因?yàn)槠渌暮瘮?shù)實(shí)現(xiàn)都相同, 只是依賴的第三方對(duì)象被替換為了假的實(shí)現(xiàn)):

    class SingletonClientInTestEnvironment extends SingletonClient {

      protected SingletonObject getServiceObject() {

        returnnew SingletonObjectStub();

      }

    }

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

    那就不要定義同名的類, #define 一個(gè)宏加一層間接, 恰當(dāng)?shù)臅r(shí)候 #undef. 如果是函數(shù), 可以定義一個(gè)函數(shù)對(duì)象來封裝想假冒的函數(shù), 生成該函數(shù)對(duì)象類型的一個(gè)變量時(shí), 使用與函數(shù)相同的名字, 利用名字的作用域規(guī)則來遮蓋原來的函數(shù).



    評(píng)論

    # re: 假冒的藝術(shù)  回復(fù)  更多評(píng)論   

    2013-02-28 10:33 by 王鵬飛
    哦,測(cè)試與開發(fā)的融合

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 国产精品日本亚洲777| 色天使亚洲综合在线观看| fc2免费人成在线视频| 午夜国产大片免费观看| 国产精品成人亚洲| 亚洲国产精品视频| 成人午夜免费视频| 国产亚洲精品线观看动态图| 中文字幕永久免费| 亚洲Av无码精品色午夜| 亚洲视频免费在线看| 久久精品国产亚洲av麻豆蜜芽 | 亚洲中文字幕乱码AV波多JI | 免费又黄又爽的视频| 美女隐私免费视频看| 亚洲一区精品伊人久久伊人| 两个人日本WWW免费版| 亚洲AV无码码潮喷在线观看| 在线看无码的免费网站| 亚洲中文字幕久久精品无码VA| 永久黄网站色视频免费| 二级毛片免费观看全程| 亚洲成AV人片在线播放无码| 青青青国产在线观看免费| 亚洲风情亚Aⅴ在线发布| 亚洲国产成人a精品不卡在线| 三级黄色在线免费观看| 亚洲日本国产乱码va在线观看| 欧美a级在线现免费观看| 美女免费视频一区二区| 久久精品国产99精品国产亚洲性色| 亚洲网站在线免费观看| 女bbbbxxxx另类亚洲| 亚洲AV无码AV男人的天堂| 成人免费午夜在线观看| 精品国产呦系列在线观看免费 | 99久久人妻精品免费一区| 亚洲色大成网站www| 亚洲精品无码鲁网中文电影| 欧美男同gv免费网站观看| 中文在线观看免费网站|