qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          接口與單元測試隨想

           剛才看到一則關于TDD的新聞,挺雷的......然后又想起以前跟別人解釋關于為什么在Spring里需要先寫個接口XXXInterface,然后再寫實現類XXXInterfaceImpl的問題。寫一點自己的想法,關于單元測試

            一個情景:

            一個User類,提供一個靜態方法:(這里不討論框架或者異常控制流程的正確性)

          public class User{

           public static User login(String username,String password) throw LoginException{
            //取得DAO
            //查詢是否存在用戶,如果存在,返回User,否則拋出異常
           }
           
           //其他全略
          }

            下面討論如何對這個方法進行測試:

            單純對于這個模塊進行單元測試:

          public class UserTest{

           public void testLogin(){
            User user = User.login("aaa", "123456");
            //對于user的正確性進行判定
           }
          }

            這樣的測試,正確性和速度實際上都保證不了。因為login中引入了數據庫的各種操作,各種未知的可能性都是存在的。比如說數據庫并未配置正確或者數據庫當前無法訪問,直接會導致這個測試失敗,但測試失敗并不意味著User.login方法錯了。同時,由于訪問數據庫造成的速度可能使這么一個簡單的測試需要幾百毫秒甚至幾秒,那么大量的測試用例加在一起,如文中提到的花費個幾十分鐘是絕對可能的。

            實際上這個簡單的測試方案違背了單元測試的基本原則:單元測試應該測試獨立的單元模塊,這個單元不應依賴于其他模塊。在這里顯然這個Login的方法使用DAO中的一些方法。

            下面討論DAO:

          public class UserDAO implements DAO<User>{
           //各種方法的實現
          }

          public class DAOFactory{
           public DAO getDAO(Class pojoClass){
            //獲取各種DAO
           }

           public static DAOFactory getInstance(){
            //單例工廠
           }
          }

            一般來說DAO部分都跟上面的差不多(或許是直接注入進User的,但實際原理是一致的):一共兩個步驟:1、獲取DAO;2、使用DAO。為了不讓User的測試受到DAO部分的干擾,就需要使用Mock技術,對DAO對象進行模擬,保證其各種方法的正確性。然后當User類需要獲取DAO時,將MockUserDAO代替UserDAO交給它。

          public class MockUserDAO implements DAO<User>{
           //肯定準確的實現
          }

            而DAOFactory由于是單例,其方法getInstance是靜態的,所以最后只能靠修改原始代碼來實現獲得另一個工廠——也就是MockDAOFactory。如果在程序員和單元測試人員不是同一個人的時候,真的是非常麻煩的事情..... (從這個角度上將,我極力反對靜態方法)雖說這種情形可以靠反射來進行偽造實例的活動,但是這種解決方案總是有一種黑客的感覺....

            另外就是如果DAO不是接口,而只有實現(這并不是不可能的情況,在有通用DAO的前提下,完全可以達到),情況也會很麻煩。由于DAO不是接口,導致無法Mock這個DAO。也許可以使用MockDAO extends DAO的方案,但也許在DAO的構造方法中依舊有著連接數據庫,初始化連接池,初始化日志等等的初始化過程,由于其在構造方法中,是無法覆蓋掉的。在這種情況下,就只能通過重構來實現測試了。(這也就是即使只有一個實現,也要盡量寫一個接口的原因)

            單元測試是至關重要的,我個人認為,如果一個團隊中的程序員頭腦都不錯,那么包括getter和setter都應該測試。單元測試的度基本上可以說是寧濫勿缺的。

            挺雜亂的,不過只是隨想,所以也無所謂。

            原文鏈接:http://my.oschina.net/Jeky/blog/30354

          posted on 2013-05-08 10:34 順其自然EVO 閱讀(561) 評論(0)  編輯  收藏 所屬分類: 敏捷測試

          <2013年5月>
          2829301234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 即墨市| 湘西| 阿巴嘎旗| 开阳县| 涞源县| 湖口县| 望谟县| 文化| 杭锦旗| 巫溪县| 盐源县| 万山特区| 黄浦区| 青田县| 界首市| 清丰县| 永定县| 信宜市| 汝州市| 金坛市| 循化| 泸西县| 佛冈县| 玉环县| 乌恰县| 北流市| 宜阳县| 江华| 吉安县| 洱源县| 镇赉县| 武城县| 长顺县| 安平县| 阳新县| 宣汉县| 共和县| 霍林郭勒市| 西畴县| 略阳县| 昌黎县|