隨筆-17  評論-0  文章-4  trackbacks-0

          本節(jié)是單元測試的第三篇。我以為這是重中之重的一章。單元測試的關(guān)鍵在于代碼要可測。可測才能測。要做好單元測試,就必須在代碼的可測性方面努力,在設(shè)計、重構(gòu)方面用心。本篇主要分享我在如何寫出可測性代碼方面的理解,與大家共勉!

          單元測試(提升篇)

          ------編寫可測試性代碼

          一、可測試性設(shè)計

          1.       接口依賴

          這是最重要的一點,因為這可以使得我們很容易的針對一個接口實現(xiàn)Mock對象,模擬/替換實際對象會變的很容易。達到使一個被測對象處于一個孤立環(huán)境的測試要求。


          這里,ClassA依賴于ClassB的具體實現(xiàn),TestCase根本無法獨立于ClassBClassA進行獨立測試。


          因此,我們將ClassA改為依賴于接口B_Inf。這樣,可以很容易的實現(xiàn)一個Mock_B替換ClassBClassA進行孤立測試。

          2.       依賴注入

          一個方法對外部類的依賴,應(yīng)該是可注入的。即可以通過構(gòu)造方法、get/set方法的方式在外部將依賴關(guān)系注入。事實上,這也為我們在測試用例中替換待測類的依賴對象提供了機會。不應(yīng)該出現(xiàn)在方法內(nèi)部新建對象使用的情況。

          3.       降低耦合度

          待測類應(yīng)與最少的類耦合,即最小交互原則。特別是要減少與那些離了具體環(huán)境就不能運行的類的耦合。可以通過門面模式等對外部調(diào)用進行隔離。

          5AOP

          面向切面編程。給我們提供的啟示是,將真正需要測的邏輯分離出來。擺脫那些無意義且簡單重復(fù)的代碼對測試的干擾。

          6.    明確的契約

          方法一定要有明確清晰的輸入/輸出。建議在方法的注釋描述中,分三段“描述”“前置條件”“后置條件”。

          二、可測試性重構(gòu)

          1.         可惡的靜態(tài)方法

          在我們的代碼中有大量的調(diào)用靜態(tài)方法的地方。用起來我們很爽,但這對測試來說卻是災(zāi)難。因為我們除了通過改變代碼創(chuàng)建stub來改變這些方法的行為外,我們沒有任何途徑。更要命的是,寫這些stub的代價非常的巨大,常常令人望而卻步。

          解決方案:

          將方法內(nèi)部的這些調(diào)用提取成protected方法。在外部創(chuàng)建待測類的子類,重寫該protected方法。

          最佳實踐:


          這些靜態(tài)方法由單態(tài)類提供,單態(tài)類由工廠方法獲取,具體類使用這些單態(tài)類的接口。

          我們在方法中通過接口使用對外部模塊的調(diào)用。一方面,隔離了外部模塊改變對我們產(chǎn)生的沖擊,另一方面,也使我們使用Mock替換實際的外部組件,創(chuàng)建孤立測試環(huán)境成為可能。

          2.         待測類方法中,new出另一個對象并使用其方法

          兩種方案:1)將new 出對象的過程封裝成protected方法。同重構(gòu)12)將該對象提取成類屬性,即由使用關(guān)系變成關(guān)聯(lián)關(guān)系。

          3.         分離不可測/不必測代碼

          在不影響的情況下,將不可測部分分離到一些不需要測的簡單方法中去。或者將可測的部分提取到一個私有方法中去。然后針對這個私有方法進行測試。

          通常這種做法使用范圍有限,但有些時候還是值的一試。

          4.         單一職責(zé)

          職責(zé)太多,肯定不好測。針對于這一點“不好測的方法必然不好用”。當(dāng)方法過大,承擔(dān)責(zé)任過多時,拆分是應(yīng)該的。

           

          5.         為類提供一個空構(gòu)造方法。

          我們的各個測試方法都依賴于對象處于一個特定的狀態(tài),滿足一定的前置條件。而要將對象置為我們希望的狀態(tài),我們必須首先擁有一個對象。然而,很多時候,在一個隔離的單元測試環(huán)境下,構(gòu)造函數(shù)由于各種原因不能正常初始化。

          此時,可以為類提供一個的空的構(gòu)造方法。在外部構(gòu)造一個對象,而后根據(jù)前置條件將各個屬性設(shè)置成需要的Mock對象。

          -----------------------------------------------------------------------------------------------------------------------------------------------------------

          事實上,要想寫出具有可測性的代碼,最佳的辦法就是測試驅(qū)動開發(fā)。先寫測試代碼把功能體現(xiàn)出來,再寫功能代碼讓測試通過。這樣寫出的代碼顯而易見會更具有測試性。


          原地址:http://www.aygfsteel.com/wukaichun600/archive/2008/07/18/214125.html

          posted on 2008-07-20 09:32 竹子 閱讀(144) 評論(0)  編輯  收藏 所屬分類: Java
          主站蜘蛛池模板: 达拉特旗| 融水| 平湖市| 察哈| 合江县| 奉新县| 永清县| 光泽县| 庆阳市| 东城区| 成武县| 荆州市| 广安市| 冕宁县| 乌拉特后旗| 梓潼县| 祁阳县| 永春县| 濉溪县| 城市| 武定县| 诸暨市| 吐鲁番市| 永胜县| 茌平县| 藁城市| 江安县| 长海县| 蓬安县| 辽中县| 平江县| 隆林| 鸡西市| 大冶市| 子长县| 兴隆县| 洞口县| 普兰店市| 丽水市| 建昌县| 梨树县|