什麼是mock測試2008-05-31 15:09
[轉] mock測試:就是在測試過程中,對於某些不容易構造或者 不容易擷取的對象,用一個虛擬對象來建立以便測試的測試方法。 mock對象:這個虛擬對象就是mock對象。mock對象就是真實對象在調試期間的代替品。 mock對象使用範疇:
- 真實對象具有不可確定的行為,產生不可預測的效果,(如:股票行情,天氣預報)
- 真實對象很難被建立的
- 真實對象的某些行為很難被觸發
- 真實對象實際上還不存在的(和其他開發小組或者和新的硬體打交道) 等等...
使用mock對象測試的關鍵步驟:
- 使用一個介面來描述這個對象
- 在產品代碼中實現這個介面
- 在測試代碼中實現這個介面
- 在被測試代碼中只是通過介面來引用對象,所以它不知道這個引用的對象是真實對象還是mock對象。
MockObject概述 使用Mock Object進行測試,主要是用來類比那些在應用中不容易構造(如HttpServletRequest必須在Servlet容器中才能構造出來)或者比較複雜的對象(如JDBC中的ResultSet對象)從而使測試順利進行的工具。 目前,在Java陣營中主要的Mock測試載入器有JMock,MockCreator,Mockrunner,EasyMock,MockMaker等,在微軟的.Net陣營中主要是Nmock,.NetMock等。 以下就對在Java中使用的Mock Object進行測試的常用工具做一下使用說明。 JMock 簡介 準備 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 簡介 準備 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.g
|