自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

進行Struts應(yīng)用程序單元測試開發(fā)

開發(fā) 后端
在Struts測試驅(qū)動開發(fā)在減少開發(fā)努力的同時也改進了軟件的開發(fā)質(zhì)量。單元測試,作為一整套測試策略的基礎(chǔ),必須是全面的,且要求易于建立和執(zhí)行迅速。

一、引言

測試驅(qū)動開發(fā)在減少開發(fā)努力的同時也改進了軟件的開發(fā)質(zhì)量。單元測試,作為一整套測試策略的基礎(chǔ),必須是全面的,且要求易于建立和執(zhí)行迅速。然而,對執(zhí)行環(huán)境和被測試類外部代碼的依賴性使我們實現(xiàn)這些目標(biāo)變得更為復(fù)雜。例如,把應(yīng)用程序發(fā)布到容器將顯著地延長代碼和測試的周期;而對其它類的依賴性通常也會導(dǎo)致測試的建立更加復(fù)雜和測試運行速度更為緩慢。
       

集成兩個流行的測試框架(StrutsTestCase和EasyMock)來單元測試Struts應(yīng)用程序?qū)鼮槿菀椎亟y試并加快測試速度。然而,這兩個框架之間尚存在一些“隔閡”,從而很難把它們理想地集成到一起。在本文中,我將通過分析兩種方案(一個面向?qū)ο蟮姆桨负鸵粋€面向方面的方案)來探討這個問題。同時,我還將展示面向方面編程(AOP)是如何通過簡化一些看起來很困難的問題的解決方案而進一步補充面向?qū)ο缶幊?OOP)的。
   

二、集成需要
       

一個典型的Struts應(yīng)用程序既能夠展示也其所使用的執(zhí)行環(huán)境也會體現(xiàn)出類之間的依賴性問題;這是因為Struts行為(Action)是在一個servlet容器內(nèi)執(zhí)行的,并且典型情況下會調(diào)用其它的類來處理請求。模擬對象測試方法有助于消除其中不必要的依賴性。借助于繼承自基本JUnit測試集的MockStrutsTestCase類,StrutsTestCase測試框架提供了對servlet容器的一種模擬實現(xiàn)。這顯然方便了容器外測試,因而也相應(yīng)地加快了單元測試周期。另一方面,另一個測試框架—EasyMock—進一步便利了對協(xié)作類的動態(tài)模擬(Mock)。這個框架中所提供的模擬能夠用更簡單的實現(xiàn)來代替真正的類,并且添加了校驗邏輯以支持單元測試。
       

非常清楚,把這兩個框架結(jié)合在一起是非常有益的—Struts應(yīng)用程序便可以在非常真實的隔離環(huán)境下進行測試。理想情況下,你需要使用下列步驟來實現(xiàn)這樣的一個單元測試:
   

1.建立MockStrutsTestCase以便模擬servlet容器。
   

2.借助于EasyMock來模擬行為所依賴的類。
   

3.設(shè)置模擬的期望值。
   

4.把模擬注入到當(dāng)前測試的行為中。
   

5.繼續(xù)進行測試和校驗。
       

注意,上面步驟4中所執(zhí)行的依賴性注入使被測試的Struts行為遠離了其真實的協(xié)作者而與一個模擬的行為進行交互。為了把通過EasyMock生成的模擬注入到行為中,你需要從測試類內(nèi)部存取這些行為相應(yīng)的實例。遺憾的是,這里出現(xiàn)了一種障礙,因為我們無法輕易地從MockStrutsTestCase中實現(xiàn)這樣的存取。
   

三、OOP方案
       

那么,你該如何從MockStrutsTestCase中存取行為實例呢?首先,讓我們來分析一下MockStrutsTestCase和Struts的控制器組件之間的關(guān)系。
       

圖1中展示的關(guān)鍵關(guān)系有可能潛在地導(dǎo)致一種解決上面問題的方案。
     

 struts   
       

圖1:此處展示的關(guān)系能夠建立一種OOP方案
       

 .MockStrutsTestCase中提供了一個public類型的getter方法用于檢索ActionServlet。
       

.ActionServlet有一個protected類型的getter方法用于實現(xiàn)RequestProcessor。
       

.RequestProcessor把行為實例存儲為一個protected類型的成員。
       

你是否可以子類化ActionServlet和RequestProcessor從而使MockStrutsTestCase能夠存取行為呢?相應(yīng)的結(jié)果調(diào)用鏈看上去應(yīng)該如下所示:

struts"" 

       

注意,在你分析完把MockStrutsTestCase鏈接到Struts行為的調(diào)用序列圖之后,你就會發(fā)現(xiàn)此方法是行不通的。
       

圖2展示了存在于MockStrutsTestCase和Struts組件之間的關(guān)鍵性交互。
       
   

  struts""   

圖2:存在于MockStrutsTestCase和Struts組件之間的交互
       

圖2展示的問題涉及到Struts行為創(chuàng)建的時序問題。到行為內(nèi)部的模擬注入必須在調(diào)用MockStrutsTestCase.actionPerform()之前發(fā)生。然而,此時這些行為還不可用,因為只有在調(diào)用actionPerform()后,Requ

estProcessor才能夠創(chuàng)建這些行為實例。
       

既然你不能很容易地把行為實例傳播到MockStrutsTestCase中,那么,為什么不子類化RequestProcessor并重載processActionCreate()方法呢?在這個重載方法中,你可以存取所有的行為實例;這樣以來,創(chuàng)建、配置和設(shè)置對相應(yīng)行為實例的一個模擬一下子變得非常直接。因為應(yīng)該在執(zhí)行完actionPerform()之后調(diào)用MockControl.verify()方法,所以,你還需要重載processActionPerform()以進行此校驗調(diào)用。
       

這種方案對于測試正規(guī)的Struts應(yīng)用程序是不太適合的。因為即使所有的行為僅與單個模擬進行交互,測試一個行為也有可能要求多個測試方法—每個方法都具有不同的模擬期望。為此,我們建議的方案是:創(chuàng)建不同的RequestProcessor子類,相應(yīng)于每個子類設(shè)置不同的模擬期望。另外,還需要多個Struts配置文件來指定不同的RequestProcessor子類。最終,管理大量的測試將成為一件令人頭疼的事情。

 

#p#

四、AOP方案
       

因此,我們非常希望,在執(zhí)行某行為之前能夠通過某種方式實現(xiàn)在MockStrutsTestCase中使用該行為的實例。如果你熟悉AOP,那么,你會立即意識到它所提供的簡單方案即能直接滿足這一要求。注意:這里的關(guān)鍵是定義一個切點,由它負責(zé)捕獲行為執(zhí)行連接點;然后通過一個before advice把模擬注入到相應(yīng)的行為中。
       

在此,我選擇使用AspectJ框架來實現(xiàn)這一方案。當(dāng)然,其它的例如Spring AOP這樣的AOP實現(xiàn)也應(yīng)該能夠良好工作。不過,Spring AOP還需要一個額外的步驟—通過Spring框架中的DelegatingActionProxy類把對Struts行為的管理委托給Spring。
       

圖3展示了基于AOP方案的單元測試示例靜態(tài)模型。
     

struts""    
      

圖3:基于AOP方案的單元測試示例靜態(tài)模型
       

 SimpleAction是一個Struts行為的子類,同時與ActionService進行協(xié)作。其中,SimpleActionTest派生于MockStrutsTestCase,用來測試SimpleAction。
       

SimpleActionTest使用EasyMock創(chuàng)建和建立一個模擬ActionService。SimpleActionTest還實現(xiàn)StrutsActionPreExecuteListener接口以便在即將運行        SimpleAction的execute方法時接收通知。作為通知的一部分,SimpleActionTest接收SimpleAction實例以便注入ActionService模擬。由方面類StrutsActionPreExecuteNotifier負責(zé)通知任何實現(xiàn)監(jiān)聽器接口的測試類,并且使相應(yīng)的行為實例可用。
       

下面的步驟描述了實現(xiàn)StrutsActionPreExecuteNotifier的過程:
       

 ◆首先,由一個切點選擇相應(yīng)的測試方法執(zhí)行連接點。另一方面,這個測試方法駐留于負責(zé)監(jiān)聽該行為的預(yù)執(zhí)行事件的測試類中。另外,這個切點還會暴露當(dāng)前執(zhí)行的測試類對象: pointcut mockStrutsTest(StrutsActionPreExecuteListener actionTest):
  
        

struts"" 
       

◆然后,由第二個切點負責(zé)捕獲上面的行為執(zhí)行連接點。通過結(jié)合第一個切點,匹配范圍被限制到該行為相應(yīng)的測試方法的調(diào)用流程的內(nèi)部。這種進一步縮小的范圍對行為執(zhí)行(并非通過測試方法激活)起到過濾作用。最終,方面根本不會影響到最后生成的代碼。該行為及其相應(yīng)的測試類實例都是經(jīng)由切點參數(shù)加以暴露的: pointcut strutsActionExecute(Action action, StrutsActionPreExecuteListener actionTest):
  
       

struts"" 
       

◆最后,由一個與前一個切點相關(guān)聯(lián)的before advice負責(zé)通知測試類(它們擔(dān)任行為事件的監(jiān)聽器)并且傳遞相應(yīng)于模擬注入的行為實例:
       
 

struts"" 
       

圖4展示了這些類之間的動態(tài)交互情形。
       
    

 struts""   

 圖4:類之間的動態(tài)交互
       

注意,圖中從行為到方面的虛線描述了對行為執(zhí)行連接點的捕獲情況。此時序圖與第一個時序圖比較,其重要區(qū)別正在于行為執(zhí)行之前發(fā)生的三個步驟:
       

1.一個切點捕獲行為執(zhí)行連接點(由從SimpleAction指向StrutsActionPreExecuteNotifier的虛線箭頭指出)。
       

2.方面的before advice負責(zé)通知測試類并且把相應(yīng)的行為實例傳遞給它。
       

3.測試類把模擬對象注入到即將要開始執(zhí)行的行為實例中。

#p#

現(xiàn)在,你可以基于前面概括的五個步驟繼續(xù)編寫行為測試。下面的代碼展示了相應(yīng)于SimpleActionTest的部分代碼,步驟已在注釋中標(biāo)出。
       

使用MockStrutsTestCase和EasyMock進行行為測試的部分代碼:
       
       

struts"" 

struts"" 

在行動及其依賴的服務(wù)之間存在四種可能的復(fù)合關(guān)系:

每個行為依賴于一個服務(wù)。

每個行為依賴于多個服務(wù)。 

多個行為依賴于一個服務(wù)。 

多個行為依賴于多個服務(wù)。 

我在此展示的方案能夠比較靈活而且相對容易地支持上面所有這四種情形,因為模擬創(chuàng)建、期望值建立以及模擬注入都能夠在單個的測試類內(nèi)實現(xiàn)。

你能夠不借助于監(jiān)聽器接口就可以在StrutsActionPreExecuteNotifier內(nèi)部模擬注入嗎?這看起來似乎使得測試類實現(xiàn)更簡單一些。然而,實踐證明,類似早些時候討論的OOP方案,編寫多個方面以創(chuàng)建不同的模擬對象并建立相應(yīng)的不同的模擬期望是非常必要的。另外,在單個測試類內(nèi)本地化模擬的創(chuàng)建與安裝(借助于監(jiān)聽技術(shù),這是可能的)將變得更為方便。

五、總結(jié)

對于我們在本文中所討論的集成問題,有人可能會創(chuàng)造出一套相當(dāng)不錯的OOP方案。然而,構(gòu)造這種方案很可能需要對Struts和StrutsTestCase有深入的理解才行,并且要付出相當(dāng)?shù)呐?。影響本文中所討論的兩個測試框架(StrutsTestCase和EasyMock)緊密集成的主要障礙在于,在Struts行為實例執(zhí)行之前很難實現(xiàn)對它的訪問。在認識了導(dǎo)致這種障礙的基本原因之后,AOP方案自然地出現(xiàn)在我們面前。不必再強求于基于傳統(tǒng)型OOP的那種更復(fù)雜的方案,AOP允許我們把我們的方案更為緊密地映射到問題空間。

其實,AOP的真正“魔術(shù)”在于它的連接點模型,它能夠使你“穿越”中間對象(例如ActionServlet和RequestProcessor)進而直指問題的核心。借助于AOP技術(shù)中確定橫切關(guān)注點這種非常“節(jié)儉”的方法,開發(fā)者即能夠設(shè)計出非常直觀而且更為簡單的解決方案。AOP,這種強有力的編程方法正好彌補了傳統(tǒng)型OOP編程中所存在的不足。如果被恰當(dāng)用于解決適當(dāng)類型的問題,那么,AOP有助于改進代碼的模塊化,最終會產(chǎn)生出更為清晰和更易于理解的代碼。最后,非常希望本文不僅有助于你的Struts應(yīng)用程序的單元測試,而且還吸引你進一步探討AOP編程所體現(xiàn)出來的其它重要優(yōu)點。

您正在閱讀的是《進行Struts應(yīng)用程序單元測試開發(fā)

【編輯推薦】

  1. 在Eclipse中開發(fā)struts應(yīng)用程序
  2. 手把手教你在Eclipse中配置開發(fā)Struts
  3. Eclipse下開發(fā)struts完整解決亂碼問題
責(zé)任編輯:張燕妮 來源: IT168
相關(guān)推薦

2017-01-14 23:26:17

單元測試JUnit測試

2017-01-16 12:12:29

單元測試JUnit

2013-06-04 09:49:04

Spring單元測試軟件測試

2023-12-11 08:25:15

Java框架Android

2017-03-23 16:02:10

Mock技術(shù)單元測試

2011-08-11 13:02:43

Struts2Junit

2011-07-27 13:39:28

iOS GH-Unit 單元測試

2017-01-14 23:42:49

單元測試框架軟件測試

2021-03-28 23:03:50

Python程序員編碼

2022-04-08 09:01:56

腳本Go應(yīng)用單元

2009-06-01 09:13:52

ASP.NET MVCMVC應(yīng)用ASP.NET MVC

2009-08-19 09:00:48

單元測試框架自動化測試

2021-03-24 09:30:02

Jupyter not單元測試代碼

2012-11-01 11:32:23

IBMdw

2012-11-01 11:37:05

JavaScript單元測試測試工具

2023-08-02 13:59:00

GoogleTestCTest單元測試

2022-06-30 09:20:32

單元測試測試

2023-08-11 07:59:15

2023-10-07 08:49:56

測試驅(qū)動開發(fā)Xunit 框架

2011-06-20 16:41:59

單元測試
點贊
收藏

51CTO技術(shù)棧公眾號