qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問(wèn) http://qaseven.github.io/

          接口與單元測(cè)試隨想

           剛才看到一則關(guān)于TDD的新聞,挺雷的......然后又想起以前跟別人解釋關(guān)于為什么在Spring里需要先寫(xiě)個(gè)接口XXXInterface,然后再寫(xiě)實(shí)現(xiàn)類(lèi)XXXInterfaceImpl的問(wèn)題。寫(xiě)一點(diǎn)自己的想法,關(guān)于單元測(cè)試

            一個(gè)情景:

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

          public class User{

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

            下面討論如何對(duì)這個(gè)方法進(jìn)行測(cè)試:

            單純對(duì)于這個(gè)模塊進(jìn)行單元測(cè)試:

          public class UserTest{

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

            這樣的測(cè)試,正確性和速度實(shí)際上都保證不了。因?yàn)閘ogin中引入了數(shù)據(jù)庫(kù)的各種操作,各種未知的可能性都是存在的。比如說(shuō)數(shù)據(jù)庫(kù)并未配置正確或者數(shù)據(jù)庫(kù)當(dāng)前無(wú)法訪(fǎng)問(wèn),直接會(huì)導(dǎo)致這個(gè)測(cè)試失敗,但測(cè)試失敗并不意味著User.login方法錯(cuò)了。同時(shí),由于訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)造成的速度可能使這么一個(gè)簡(jiǎn)單的測(cè)試需要幾百毫秒甚至幾秒,那么大量的測(cè)試用例加在一起,如文中提到的花費(fèi)個(gè)幾十分鐘是絕對(duì)可能的。

            實(shí)際上這個(gè)簡(jiǎn)單的測(cè)試方案違背了單元測(cè)試的基本原則:?jiǎn)卧獪y(cè)試應(yīng)該測(cè)試獨(dú)立的單元模塊,這個(gè)單元不應(yīng)依賴(lài)于其他模塊。在這里顯然這個(gè)Login的方法使用DAO中的一些方法。

            下面討論DAO:

          public class UserDAO implements DAO<User>{
           //各種方法的實(shí)現(xiàn)
          }

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

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

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

          public class MockUserDAO implements DAO<User>{
           //肯定準(zhǔn)確的實(shí)現(xiàn)
          }

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

            另外就是如果DAO不是接口,而只有實(shí)現(xiàn)(這并不是不可能的情況,在有通用DAO的前提下,完全可以達(dá)到),情況也會(huì)很麻煩。由于DAO不是接口,導(dǎo)致無(wú)法Mock這個(gè)DAO。也許可以使用MockDAO extends DAO的方案,但也許在DAO的構(gòu)造方法中依舊有著連接數(shù)據(jù)庫(kù),初始化連接池,初始化日志等等的初始化過(guò)程,由于其在構(gòu)造方法中,是無(wú)法覆蓋掉的。在這種情況下,就只能通過(guò)重構(gòu)來(lái)實(shí)現(xiàn)測(cè)試了。(這也就是即使只有一個(gè)實(shí)現(xiàn),也要盡量寫(xiě)一個(gè)接口的原因)

            單元測(cè)試是至關(guān)重要的,我個(gè)人認(rèn)為,如果一個(gè)團(tuán)隊(duì)中的程序員頭腦都不錯(cuò),那么包括getter和setter都應(yīng)該測(cè)試。單元測(cè)試的度基本上可以說(shuō)是寧濫勿缺的。

            挺雜亂的,不過(guò)只是隨想,所以也無(wú)所謂。

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

          posted on 2013-05-08 10:34 順其自然EVO 閱讀(562) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): 敏捷測(cè)試

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

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類(lèi)

          隨筆檔案

          文章分類(lèi)

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 濮阳县| 赤水市| 雷波县| 嘉禾县| 马鞍山市| 响水县| 离岛区| 大安市| 云安县| 策勒县| 广灵县| 肇东市| 朝阳县| 云和县| 固始县| 正阳县| 炎陵县| 宜春市| 沾化县| 祁门县| 循化| 乐业县| 临沭县| 资兴市| 乌拉特中旗| 溧阳市| 普兰店市| 错那县| 新密市| 武山县| 玉树县| 遂昌县| 永善县| 科技| 福建省| 临邑县| 高台县| 旬阳县| 辽阳市| 额尔古纳市| 治县。|