|
使用Mock Object進(jìn)行測(cè)試,主要是用來(lái)模擬那些在應(yīng)用中不容易構(gòu)造(如HttpServletRequest必須在Servlet容器中才能構(gòu)造出來(lái))或者比較復(fù)雜的對(duì)象(如JDBC中的ResultSet對(duì)象)從而使測(cè)試順利進(jìn)行的工具。 目前,在Java陣營(yíng)中主要的Mock測(cè)試工具有JMock,MockCreator,Mockrunner,EasyMock,MockMaker等,在微軟的.Net陣營(yíng)中主要是Nmock,.NetMock等。 以下就對(duì)在Java中使用的Mock Object進(jìn)行測(cè)試的常用工具做一下使用說(shuō)明。 JMock簡(jiǎn)介請(qǐng)?jiān)L問(wèn)http://www.。 準(zhǔn)備1. 獲取J2SDK; 2. 獲取JUnit V 3. 獲取JMock V1.0(從http://www.獲取JMock開(kāi)發(fā)包)。 4. 為了開(kāi)發(fā)方便,建議使用一個(gè)好IDE。以下例子中的代碼均是在Eclipse V3.0環(huán)境下進(jìn)行的調(diào)試。 例子一以下是一個(gè)簡(jiǎn)單例子,代碼如下: package test1; import org.jmock.*; import javax.servlet.http.*; public class MockRequestTest extends MockObjectTestCase{ public void testMockRequest1(){ //構(gòu)造一個(gè)Mock對(duì)象 Mock mock = new Mock(HttpServletRequest.class); //設(shè)置要執(zhí)行的操作,以下設(shè)置表示要調(diào)用一次HttpServletRequest對(duì)象的 //getParameter方法,傳遞的參數(shù)是"name",期望的返回是"kongxx" mock.expects(once()).method("getParameter").with(eq("name")).will(returnValue("kongxx")); //根據(jù)Mock對(duì)象獲取一個(gè)HttpServletRequest對(duì)象 HttpServletRequest request = (HttpServletRequest)mock.proxy(); //斷言調(diào)用結(jié)果 assertEquals("kongxx" ,request.getParameter("name")); } public void testMockRequest2(){ //構(gòu)造一個(gè)Mock對(duì)象 Mock mock = new Mock(HttpServletRequest.class); //設(shè)置要執(zhí)行的操作,以下設(shè)置表示要調(diào)用一次HttpServletRequest對(duì)象的 //getParameter方法,傳遞的參數(shù)是"name",期望的返回是"kongxx" mock.expects(once()).method("getParameter").with(eq("name")).will(returnValue("kongxx")); //根據(jù)Mock對(duì)象獲取一個(gè)HttpServletRequest對(duì)象 HttpServletRequest request = (HttpServletRequest)mock.proxy(); //調(diào)用HttpServletRequest對(duì)象的方法 request.getParameter("name"); //驗(yàn)證執(zhí)行結(jié)果 mock.verify(); } } 編譯并將其當(dāng)做一個(gè)Test Case運(yùn)行,會(huì)發(fā)現(xiàn)兩個(gè)測(cè)試方法均測(cè)試成功。 例子二MyClass需要測(cè)試的類(lèi),提供了兩個(gè)方法getName和getPassword,都使用HttpServletRequest作為輸入?yún)?shù)并返回從HttpServletRequest中取得的參數(shù),具體代碼如下: 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測(cè)試類(lèi),其中構(gòu)造了一個(gè)假的HttpServletRequest對(duì)象,用來(lái)測(cè)試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();
//構(gòu)造一個(gè)Mock對(duì)象 mockRequest = new Mock(HttpServletRequest.class);
//根據(jù)Mock對(duì)象獲取一個(gè)HttpServletRequest對(duì)象 request = (HttpServletRequest)mockRequest.proxy(); } public void tearDown() { //TODO } public void testGetName(){ //設(shè)置要執(zhí)行的操作,以下設(shè)置表示要調(diào)用一次HttpServletRequest對(duì)象的 //getParameter方法,傳遞的參數(shù)是"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(){ //設(shè)置要執(zhí)行的操作,以下設(shè)置表示要調(diào)用一次HttpServletRequest對(duì)象的 //getParameter方法,傳遞的參數(shù)是"password",期望的返回是"123456789" mockRequest.expects(atLeastOnce()).method("getParameter").with(eq("password")).will(returnValue("123456789"));
assertNotNull(myclass.getPassword(request)); assertEquals("123456789" ,myclass.getPassword(request)); } } 編譯并將其當(dāng)做一個(gè)Test Case運(yùn)行,會(huì)發(fā)現(xiàn)兩個(gè)測(cè)試方法均測(cè)試成功。 小結(jié)無(wú) EasyMock簡(jiǎn)介請(qǐng)?jiān)L問(wèn)http://www.。 準(zhǔn)備1. 獲取J2SDK; 2. 獲取JUnit V 3. 獲取EasyMock V1.1(從http://www.獲取EasyMock開(kāi)發(fā)包)。 4. 為了開(kāi)發(fā)方便,建議使用一個(gè)好IDE。以下例子中的代碼均是在Eclipse V3.0環(huán)境下進(jìn)行的調(diào)試。 例子一以下是一個(gè)簡(jiǎn)單例子,為了方便對(duì)比,這里重新實(shí)現(xiàn)了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(){ //創(chuàng)建一個(gè)Mock HttpServletRequest的MockControl對(duì)象 control = MockControl.createControl(HttpServletRequest.class); //獲取一個(gè)Mock HttpServletRequest對(duì)象 mockRequest = (HttpServletRequest) control.getMock(); //設(shè)置期望調(diào)用的Mock HttpServletRequest對(duì)象的方法 mockRequest.getParameter("name"); //設(shè)置調(diào)用方法期望的返回值,并指定調(diào)用次數(shù) //以下后兩個(gè)參數(shù)表示最少調(diào)用一次,最多調(diào)用一次 control.setReturnValue("kongxx" ,1 ,1); //設(shè)置Mock HttpServletRequest的狀態(tài), //表示此Mock HttpServletRequest對(duì)象可以被使用 control.replay(); //使用斷言檢查調(diào)用 assertEquals("kongxx",mockRequest.getParameter("name")); //驗(yàn)證期望的調(diào)用 control.verify(); } } 編譯并將其當(dāng)做一個(gè)Test Case運(yùn)行,會(huì)發(fā)現(xiàn)兩個(gè)測(cè)試方法均測(cè)試成功。 例子二同例子一樣,對(duì)JMock例子二重新實(shí)現(xiàn)產(chǎn)生了EasyMock的例子二。 需要測(cè)試的類(lèi)代碼如下: 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"); } } 測(cè)試類(lèi)代碼如下: 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(); //創(chuàng)建一個(gè)Mock HttpServletRequest的MockControl對(duì)象 control = MockControl.createControl(HttpServletRequest.class); //獲取一個(gè)Mock HttpServletRequest對(duì)象 mockRequest = (HttpServletRequest) control.getMock(); } public void tearDown() { //TODO } public void testGetName(){ //設(shè)置期望調(diào)用的Mock HttpServletRequest對(duì)象的方法 mockRequest.getParameter("name"); //設(shè)置調(diào)用方法期望的返回值,并指定調(diào)用次數(shù) //以下后兩個(gè)參數(shù)表示最少調(diào)用一次,最多調(diào)用一次 control.setReturnValue("kongxx" ,1 ,2); //設(shè)置Mock HttpServletRequest的狀態(tài), //表示此Mock HttpServletRequest對(duì)象可以被使用 control.replay(); //使用斷言檢查調(diào)用 assertNotNull(myclass.getName(mockRequest)); assertEquals("kongxx",myclass.getName(mockRequest)); //驗(yàn)證期望的調(diào)用 control.verify(); } public void testGetPassword(){ //設(shè)置期望調(diào)用的Mock HttpServletRequest對(duì)象的方法 mockRequest.getParameter("password"); //設(shè)置調(diào)用方法期望的返回值,并指定調(diào)用次數(shù) //以下后兩個(gè)參數(shù)表示最少調(diào)用一次,最多調(diào)用一次 control.setReturnValue("kongxx" ,1,2); //設(shè)置Mock HttpServletRequest的狀態(tài), //表示此Mock HttpServletRequest對(duì)象可以被使用 control.replay(); //使用斷言檢查調(diào)用 assertNotNull(myclass.getPassword(mockRequest)); assertEquals("kongxx",myclass.getPassword(mockRequest)); //驗(yàn)證期望的調(diào)用 control.verify(); } } 編譯并將其當(dāng)做一個(gè)Test Case運(yùn)行,會(huì)發(fā)現(xiàn)兩個(gè)測(cè)試方法均測(cè)試成功。 小結(jié)無(wú) 總結(jié)無(wú) 參考資料
l http://www./介紹了關(guān)鍵Mock Object的基本概念和目前在各個(gè)環(huán)境下主要的Mock測(cè)試工具。 l JMock的主頁(yè)http://www.,可以獲取JMock的最新代碼和開(kāi)發(fā)包,以及一些說(shuō)明文檔。 l EasyMock的主頁(yè)http://www.,可以獲取JMock的最新代碼和開(kāi)發(fā)包,以及一些說(shuō)明文檔。 l NMock的主頁(yè)http://www.,介紹了在Microsoft .Net平臺(tái)上進(jìn)行Mock測(cè)試的開(kāi)發(fā)工具。 l MockCreator主頁(yè)http://mockcreator./。 l MockMaker主頁(yè)http://mockmaker./。 【日期:2006-9-3】【作者:不祥】【轉(zhuǎn)載自:開(kāi)店樂(lè)】 |
|
|