隨筆-55  評論-208  文章-0  trackbacks-0

          通常我們的bs模式應同都是5層構架體系的:DAO  BL  Action Taglib JSP
          在這5層之中,只有jsp是非java代碼的,所以也是比較難以進行單元測試的一層
          而且jsp作為表現層來說呢,通常變化也比較大。所以對jsp編寫代碼測試的代價要遠大于人工直接對頁面樣式進行測試。

          這篇文章主要將針對除去jsp以外的另外4層相關單元測試的基本框架進行了一些討論:
          首先我們要在單元測試前問自己一個問題:單元測試的目的究竟是為了什么?
          為了讓我們的項目更加時髦?為了讓我寫的代碼沒有bug?
          我個人覺得單元測試的目的就是為了能夠用輕易的重復對代碼的測試!

          下面我將對每一層的目的是什么,單元測試的目的是什么,還有改層單元測試的相關問題進行講述

          1、DAO層
          DAO的目的:根據指定的參數對相關的數據對象進行處理
                                   基本操作有查詢操作  對數據源無影響 有返回值 
                                                       增改操作 影響數據源 無返回值
                                                       刪除操作 影響數據源 無返回值

          從上面我們可以看出,DAO的test主要是針對DAO的3種操作進行測試
          對于查詢操作我們可以從返回的結果集來進行判斷
          而對于增改操作和刪除操作我們就是只能在方法調用后對數據源進行判斷了

          這里,現在一般DAO層我們都會使用Spring+hibernate來進行構建,那么一個DAO的實例就需要引入到spring和DAO的相關配置了。而且由于牽扯到外部環境,所以這里外部環境的處理可以采用兩種方式,一種是直接使用數據庫,這里就需要有一個真實的數據源存在了 二是模擬一個數據源,比如使用內存數據庫或者文本數據庫來建立一個模擬環境,方便單機進行測試

          而且由于DAO是由Spring來進行管理的,所以在測試的時候需要加載Spring的上下文來獲取dao的bean,關于spring的加載我使用的是spring-mock,它的好處是在事物處理后可以對相關的數據庫操作進行rollback

          2、BL層
          BL層的目的:根據業務邏輯對業務處理進行封裝
          以往其實我們有時候習慣把一些業務邏輯代碼放置到上層DAO或者下層Action,taglib中
          所以我總結了一下,基本的業務邏輯有:
          參數的驗證和判斷
          業務邏輯錯誤處理
          業務規則判斷

          所以針對于這些功能我們可以把原本屬于BL的代碼歸還給BL了,然后針對于bl的幾個功能就可以清晰地編寫單元測試了,這時候一般會用到做單元測試時比較有用的一個副產品:重構。而這個副產品的價值將會在你重構后體現出來,DAO,BL,ACTION,taglib的代碼職責更加明晰了,該做什么判斷的就座什么判斷

          BL這層一般也是用Spring來進行管理的,所以我們還是需要加載spring的上下文,當然也可以不加載Spring,然后根據接口模擬一個DAO出來,但是我一般覺得這種模擬花消比較大,這個代價是否值得一直是我所懷疑的

          3、Action層
          action層的目的:對于請求進行跳轉控制
          一個控制層方法的主要功能有:獲取參數,調用BL對參數進行執行,根據執行的結果進行頁面參數賦值,跳轉到結果頁面
          當然上面除了跳轉的到結果頁以外其他功能都不是必須的

          針對于上述功能action的單元測試基本框架是:封裝請求參數,發送請求,判斷所需的頁面bean和跳轉的結果頁面是否正確
          這里牽扯到對于請求環境的模擬,一般不同的前臺構架會有不同的模擬方法,struts下我使用的是strutstescase,它可以較為完整的讀取Struts配置文件

          當然一般在action中會用到Spring的上下文獲取bl,由于之前已經對bl進行了測試確認,所以我建議可以直接使用實際的bl,而不是再花費代價開發一個模擬的BL

          4、taglib層
          taglib層目的:根據參數在頁面上按照固定的樣式輸出
          一個標簽的基本功能有:獲取參數,調用BL對參數進行執行,把執行結果放到指定樣式中,把得到的頁面代碼輸出

          相對來說獲取參數,調用BL對參數進行執行,把得到的頁面代碼輸出,比較固定,測試的意義不大,所以主要測試的就是把執行結果放到指定樣式中這個功能。這個功能通常就是給一個結果集參數然后組合返回一個StringBuffer,所以測試起來也比較容易

          但是taglib在使用的時候也需要的Spring甚至Struts的配置,這就需要在初始化的時候把相關環境也要加載進來

          這里大家因該可以看出我的單元測試并不是完全獨立的,而是伴隨漸進的按照DAO,BL,Action,taglib這樣的順序引入環境,這樣一個可以減少測試開發的代價,一個是可以增加測試的準確性

          在上面的描述中我們基本上了解了4層單元測試的基本目的和結構

          下一篇文章中我會針對各個層的具體測試方法是用代碼進行講解 :)

          posted on 2007-01-16 00:42 rocket 閱讀(1589) 評論(2)  編輯  收藏

          評論:
          # re: 4層結構的單元測試構架 2007-01-16 09:13 | GHawk
          BL層確實需要造很多DAO的Mock,開銷巨大。
          但這完全取決于后臺采用什么樣的架構。如果用POJO+O/R mapping來構造Domain Model的話,應該還是比較容易測試的,當然這樣就要把BL的測試和mapping的測試分開了。
          如果后臺的BL采用Table Module這樣的模式的話,寫起測試來就比較累了,而且這樣的測試代碼對重構的支持不太友好。  回復  更多評論
            
          # re: 4層結構的單元測試構架 2007-01-17 00:39 | ssh
          下篇大概什么時候推出啊?別調胃口嘛  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
          博客園   IT新聞   Chat2DB   C++博客   博問  
           
          主站蜘蛛池模板: 义马市| 武城县| 来凤县| 林芝县| 兴海县| 阳高县| 乌拉特中旗| 黔西| 余庆县| 奎屯市| 贵阳市| 建平县| 托克托县| 大荔县| 德保县| 临汾市| 社会| 金乡县| 东乡| 长葛市| 紫云| 和林格尔县| 蓝田县| 连南| 突泉县| 娄烦县| 大港区| 临汾市| 定襄县| 锡林郭勒盟| 云霄县| 罗山县| 开化县| 南昌市| 肇庆市| 贵定县| 大英县| 金坛市| 孝义市| 砚山县| 奉贤区|