Struts測試之Mock Object測試

          Struts測試之Mock Object測試

          以下內容引自 http://www.xgdown.com/article/239/47289_1.htm

          使用Mock Object進行測試,主要是用來模擬那些在應用中不容易構造(如HttpServletRequest必須在Servlet容器中才能構造出來)或者比較復雜的對象(如JDBC中的ResultSet對象)從而使測試順利進行的工具。

          JMock

          簡介

          請訪問 http://www.jmock.org

          準備

          1.??????? 獲取 J2SDK

          2.??????? 獲取 JUnit V3.8.1 (從 http://www.junit.org 獲取開發包);

          3.??????? 獲取 JMock V1.0 (從 http://www.jmock.org 獲取 JMock 開發包)。

          4.??????? 為了開發方便,建議使用一個好 IDE 。以下例子中的代碼均是在 Eclipse V3.0 環境下進行的調試。

          例子一

          以下是一個簡單例子,代碼如下:

          package test1;

          ?

          import org.jmock.*;

          import javax.servlet.http.*;

          ?

          public class MockRequestTest extends MockObjectTestCase{

          ??? public void testMockRequest1(){

          ?????? // 構造一個 Mock 對象

          ??????? Mock mock = new Mock(HttpServletRequest.class);

          ???????

          ??????? // 設置要執行的操作,以下設置表示要調用一次 HttpServletRequest 對象的

          ??????? //getParameter 方法,傳遞的參數是 "name", 期望的返回是 "kongxx"

          ??????? mock.expects(once()).method("getParameter").with(eq("name")).will(returnValue("kongxx"));

          ???????

          ??????? // 根據 Mock 對象獲取一個 HttpServletRequest 對象

          ??????? HttpServletRequest request = (HttpServletRequest)mock.proxy();

          ???????

          ??????? // 斷言調用結果

          ??????? assertEquals("kongxx" ,request.getParameter("name"));???????

          ??? }

          ??? public void testMockRequest2(){

          ?????? // 構造一個 Mock 對象

          ??????? Mock mock = new Mock(HttpServletRequest.class);

          ???????

          ??????? // 設置要執行的操作,以下設置表示要調用一次 HttpServletRequest 對象的

          ??????? //getParameter 方法,傳遞的參數是 "name", 期望的返回是 "kongxx"

          ??????? mock.expects(once()).method("getParameter").with(eq("name")).will(returnValue("kongxx"));

          ???????

          ??????? // 根據 Mock 對象獲取一個 HttpServletRequest 對象

          ??????? HttpServletRequest request = (HttpServletRequest)mock.proxy();

          ???????

          ??????? // 調用 HttpServletRequest 對象的方法

          ??????? request.getParameter("name");???????

          ???????

          ??????? // 驗證執行結果

          ??????? mock.verify();

          ??? }

          }

          編譯并將其當做一個 Test Case 運行,會發現兩個測試方法均測試成功。

          例子二

          MyClass 需要測試的類,提供了兩個方法 getName getPassword ,都使用 HttpServletRequest 作為輸入參數并返回從 HttpServletRequest 中取得的參數,具體代碼如下:

          package test2;

          ?

          import javax.servlet.http.*;

          ?

          public class MyClass {

          ??? public String getName(HttpServletRequest request) {

          ?????? return request.getParameter("name");

          ??? }

          ???

          ??? public String getPassword(HttpServletRequest request) {

          ?????? return request.getParameter("password");

          ??? }

          }

          TestMyClass 測試類,其中構造了一個假的 HttpServletRequest 對象,用來測試 MyClass 中的 getName getPassword 方法,代碼如下:

          package test2;

          ?

          import org.jmock.*;

          import javax.servlet.http.*;

          ?

          public class TestMyClass extends MockObjectTestCase{

          ??? private MyClass myclass ;

          ??? private Mock mockRequest ;

          ??? private HttpServletRequest request ;

          ???

          ??? public void setUp() {??????

          ?????? myclass = new MyClass();

          ??????

          ?????? // 構造一個 Mock 對象

          ?????? mockRequest = new Mock(HttpServletRequest.class);

          ??????

          ?????? // 根據 Mock 對象獲取一個 HttpServletRequest 對象

          ?????? request = (HttpServletRequest)mockRequest.proxy();

          ??? }

          ??? public void tearDown() {

          ?????? //TODO

          ??? }

          ??? public void testGetName(){

          ?????? // 設置要執行的操作,以下設置表示要調用一次 HttpServletRequest 對象的

          ??????? //getParameter 方法,傳遞的參數是 "name", 期望的返回是 "kongxx"?????

          ?????? mockRequest.expects(atLeastOnce()).method("getParameter").with(eq("name")).will(returnValue("kongxx"));

          ??????

          ?????? assertNotNull(myclass.getName(request));

          ??????? assertEquals("kongxx" ,myclass.getName(request));??????

          ??? }

          ??? public void testGetPassword(){

          ?????? // 設置要執行的操作,以下設置表示要調用一次 HttpServletRequest 對象的

          ??????? //getParameter 方法,傳遞的參數是 "password", 期望的返回是 "123456789" ?

          ??? ??? mockRequest.expects(atLeastOnce()).method("getParameter").with(eq("password")).will(returnValue("123456789"));

          ??????

          ?????? assertNotNull(myclass.getPassword(request));

          ??????? assertEquals("123456789" ,myclass.getPassword(request));

          ??? }

          }

          編譯并將其當做一個 Test Case 運行,會發現兩個測試方法均測試成功。

          ?

          EasyMock

          簡介

          請訪問 http://www.easymock.org

          準備

          1. ??????? 獲取 J2SDK

          2. ??????? 獲取 JUnit V3.8.1 (從 http://www.junit.org 獲取開發包);

          3. ??????? 獲取 EasyMock V1.1 (從 http://www.easymock.org 獲取 EasyMock 開發包)。

          4. ??????? 為了開發方便,建議使用一個好 IDE 。以下例子中的代碼均是在 Eclipse V3.0 環境下進行的調試。

          例子一

          以下是一個簡單例子,為了方便對比,這里重新實現了 JMock 例子一 ,代碼如下:

          package test1;

          ?

          import org.easymock.*;

          import junit.framework.*;

          import javax.servlet.http.*;

          ?

          public class MockRequestTest extends TestCase{

          ??? private MockControl control;

          ??? private HttpServletRequest mockRequest;

          ?

          ??? public void testMockRequest(){

          ?????? // 創建一個 Mock HttpServletRequest MockControl 對象

          ?????? control = MockControl.createControl(HttpServletRequest.class);

          ??????

          ?????? // 獲取一個 Mock HttpServletRequest 對象

          ?????? mockRequest = (HttpServletRequest) control.getMock();

          ??????????

          ?????? // 設置期望調用的 Mock HttpServletRequest 對象的方法

          ?????? mockRequest.getParameter("name");

          ??????

          ?????? // 設置調用方法期望的返回值,并指定調用次數

          ?????? // 以下后兩個參數表示最少調用一次,最多調用一次

          ?????? control.setReturnValue("kongxx" ,1 ,1);??

          ??????

          ?????? // 設置 Mock HttpServletRequest 的狀態,

          ?????? // 表示此 Mock HttpServletRequest 對象可以被使用

          ?????? control.replay();

          ??????

          ?????? // 使用斷言檢查調用

          ?????? assertEquals("kongxx",mockRequest.getParameter("name"));

          ??????

          ?????? // 驗證期望的調用

          ?????? control.verify();

          ??? }

          }

          編譯并將其當做一個 Test Case 運行,會發現兩個測試方法均測試成功。

          例子二

          同例子一樣,對 JMock 例子二 重新實現產生了 EasyMock 的例子二。

          需要測試的類代碼如下:

          package test2;

          ?

          import javax.servlet.http.*;

          ?

          public class MyClass {

          ??? public String getName(HttpServletRequest request) {

          ?????? return request.getParameter("name");

          ??? }

          ???

          ??? public String getPassword(HttpServletRequest request) {

          ?????? return request.getParameter("password");

          ??? }

          }

          測試類代碼如下:

          package test2;

          ?

          import org.easymock.*;

          import junit.framework.*;

          import javax.servlet.http.*;

          ?

          public class TestMyClass extends TestCase{

          ???

          ??? private MockControl control;

          ??? private HttpServletRequest mockRequest;

          ??? private MyClass myclass ;

          ???

          ??? public void setUp() {??????

          ?????? myclass = new MyClass();

          ??????

          ?????? // 創建一個 Mock HttpServletRequest MockControl 對象

          ?????? control = MockControl.createControl(HttpServletRequest.class);

          ??????

          ?????? // 獲取一個 Mock HttpServletRequest 對象

          ?????? mockRequest = (HttpServletRequest) control.getMock();??????

          ??? }

          ??? public void tearDown() {

          ?????? //TODO

          ??? }

          ??? public void testGetName(){

          ?????? // 設置期望調用的 Mock HttpServletRequest 對象的方法

          ?????? mockRequest.getParameter("name");

          ??????

          ?????? // 設置調用方法期望的返回值,并指定調用次數

          ?????? // 以下后兩個參數表示最少調用一次,最多調用一次

          ?????? control.setReturnValue("kongxx" ,1 ,2);??

          ??????

          ?????? // 設置 Mock HttpServletRequest 的狀態,

          ?????? // 表示此 Mock HttpServletRequest 對象可以被使用

          ?????? control.replay();

          ??????

          ?????? // 使用斷言檢查調用

          ?????? assertNotNull(myclass.getName(mockRequest));

          ?????? assertEquals("kongxx",myclass.getName(mockRequest));

          ??????

          ?????? // 驗證期望的調用

          ?????? control.verify();???

          ??? }

          ??? public void testGetPassword(){

          ?????? // 設置期望調用的 Mock HttpServletRequest 對象的方法

          ?????? mockRequest.getParameter("password");

          ??????

          ?????? // 設置調用方法期望的返回值,并指定調用次數

          ?????? // 以下后兩個參數表示最少調用一次,最多調用一次

          ?????? control.setReturnValue("kongxx" ,1,2);

          ??????

          ?????? // 設置 Mock HttpServletRequest 的狀態,

          ?????? // 表示此 Mock HttpServletRequest 對象可以被使用

          ?????? control.replay();

          ??????

          ?????? // 使用斷言檢查調用

          ?????? assertNotNull(myclass.getPassword(mockRequest));

          ?????? assertEquals("kongxx",myclass.getPassword(mockRequest));

          ??????

          ?????? // 驗證期望的調用

          ?????? control.verify();??

          ??? }

          }

          編譯并將其當做一個 Test Case 運行,會發現兩個測試方法均測試成功。


          獨立測試就是單獨測試一個類或方法里的代碼,而不測試里面調用的其他類或方法的代碼。即假定調用的其他類或方法都正常執行。

        1. 使用Mock Object的場合
          1. 實際對象的行為還不確定。
          2. 實際的對象創建和初始化非常復雜。
          3. 實際對象中存在很難執行到的行為(如網絡異常等)。
          4. 實際的對象運行起來非常的慢。
          5. 實際對象是用戶界面程序。
          6. 實際對象還沒有編寫,只有接口等。
        2. 簡單分析用Mock Object的原因

          假定我們有對象A,它內部頻繁調用了B中的方法。但是除了調用B的部分還存在自己的邏輯代碼。這時,我們只想寫A的單體測試,而不想測試B(因為B可能還沒編寫,只寫了實現的接口或者B運行太慢了影響我們的測試效率)。這樣的話,我們就需要創建B的Mock對象。

          換言之,我們現在不關心B,我們假定B的行為都能正常運行。我們的目標是假定B運行正常的情況下,來對A進行單體測試。

          Mock對象就是我們先不用關心的對象,但是我們的關注對象對它有調用,所以我們給關注對象準備個假貨讓它用。

          ?

        3. posted on 2006-02-17 09:02 扭轉乾坤 閱讀(544) 評論(0)  編輯  收藏 所屬分類: Struts相關

          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          導航

          統計

          常用鏈接

          留言簿(2)

          隨筆分類(31)

          隨筆檔案(30)

          文章分類(32)

          文章檔案(33)

          相冊

          PHP小站-首頁

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 宿松县| 土默特右旗| 无为县| 健康| 五指山市| 尉氏县| 兴安盟| 潜山县| 昂仁县| 贵德县| 张家川| 嘉定区| 白城市| 高邮市| 辽宁省| 忻州市| 通榆县| 张家口市| 祁门县| 沛县| 化德县| 崇文区| 云龙县| 崇仁县| 海兴县| 循化| 宜城市| 沾化县| 洪湖市| 长葛市| 许昌市| 台前县| 称多县| 抚州市| 民乐县| 汾阳市| 新干县| 通江县| 礼泉县| 八宿县| 日喀则市|