posts - 56, comments - 77, trackbacks - 0, articles - 1
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          假冒的藝術(shù)

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

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

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

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

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

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

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

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

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

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

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

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

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

          • 利用名稱作用范圍, 同名局部變量可遮擋其它名字等, 來(lái)控制接入真正的實(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)語(yǔ)言, 直接在測(cè)試前重定義

          • 編譯型靜態(tài)語(yǔ)言, 運(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ù)訪問(wèn), static訪問(wèn), new 操作符, 可以子類化以接入假的實(shí)現(xiàn)" 來(lái)進(jìn)行測(cè)試.

          public class SingletonClient {

           publicvoid doSomething(){

              SingletonObject service = SingletonObject.instance();

              service.execute();

            }

          }

          上面的這個(gè)SingletonClient的doSomething是無(wú)法測(cè)試的, 因?yàn)橐昧艘粋€(gè)靜態(tài)函數(shù). 可以把對(duì)靜態(tài)函數(shù)的引用抽取到一個(gè)可覆寫的函數(shù)中來(lái)引入接入點(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í)如何解決鏈接問(wèn)題? (重定義)

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



          評(píng)論

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

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

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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 孝义市| 黑水县| 宜兴市| 衡阳市| 阳江市| 乐都县| 奉贤区| 察哈| 吉林省| 永春县| 商河县| 乡城县| 兴海县| 道孚县| 广水市| 靖西县| 水城县| 荥阳市| 翁牛特旗| 报价| 临泽县| 德江县| 南丹县| 阿巴嘎旗| 海原县| 原阳县| 佛教| 全州县| 汾阳市| 卢氏县| 水富县| 灌南县| 古蔺县| 景东| 长岛县| 横峰县| 尼玛县| 舟曲县| 同德县| 思南县| 巴塘县|