欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
使用EasyMock使單元測試更加容易
作者:xuefeng    文章來(lái)源:本站原創(chuàng )    點(diǎn)擊數:61    更新時(shí)間:2006-2-25
單元測試是XP極力推薦的測試驅動(dòng)開(kāi)發(fā)模式,是保證軟件質(zhì)量的重要方法。盡管如此,對許多類(lèi)的單元測試仍然是極其困難的,例如,對數據庫操作的類(lèi)進(jìn)行測試,如果不準備好數據庫環(huán)境以及相關(guān)測試數據,是很難進(jìn)行單元測試的;再例如,對需要運行在容器內的Servlet或EJB組件,脫離了容器也難于測試。
幸運的是,Mock Object可以用來(lái)模擬一些我們需要的類(lèi),這些對象被稱(chēng)之為模仿對象,在單元測試中它們特別有價(jià)值。
Mock Object用于模仿真實(shí)對象的方法調用,從而使得測試不需要真正的依賴(lài)對象。Mock Object只為某個(gè)特定的測試用例的場(chǎng)景提供剛好滿(mǎn)足需要的最少功能。它們還可以模仿錯誤的條件,例如拋出指定的異常等。
目前,有許多可用的Mock類(lèi)庫可供我們選擇。一些Mock庫提供了常見(jiàn)的模仿對象,例如:HttpServletRequest,而另一些Mock庫則提供了動(dòng)態(tài)生成模仿對象的功能,本文將討論使用EasyMock動(dòng)態(tài)生成模仿對象以便應用于單元測試。
到目前為止,EasyMock提供了1.2版本和2.0版本,2.0版本僅支持Java SE 5.0,本例中,我們選擇EasyMock 1.2 for Java 1.3版本進(jìn)行測試,可以從http://www.easymock.org下載合適的版本。
我們首先來(lái)看一個(gè)用戶(hù)驗證的LoginServlet類(lèi):
/**
* LoginServlet.java
* Author: Liao Xue Feng,www.crackj2ee.com
*/
package com.crackj2ee.test.mock;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
// check username & password:
if("admin".equals(username) && "123456".equals(password)) {
ServletContext context = getServletContext();
RequestDispatcher dispatcher = context.getNamedDispatcher("dispatcher");
dispatcher.forward(request, response);
}
else {
throw new RuntimeException("Login failed.");
}
}
}
這個(gè)Servlet實(shí)現簡(jiǎn)單的用戶(hù)驗證的功能,若用戶(hù)名和口令匹配“admin”和“123456”,則請求被轉發(fā)到指定的dispatcher上,否則,直接拋出RuntimeException。
為了測試doPost()方法,我們需要模擬HttpServletRequest,ServletContext和RequestDispatcher對象,以便脫離J2EE容器來(lái)測試這個(gè)Servlet。
我們建立TestCase,名為L(cháng)oginServletTest:
public class LoginServletTest extends TestCase {
}
我們首先測試當用戶(hù)名和口令驗證失敗的情形,演示如何使用EasyMock來(lái)模擬HttpServletRequest對象:
public void testLoginFailed() throws Exception {
MockControl mc = MockControl.createControl(HttpServletRequest.class);
HttpServletRequest request = (HttpServletRequest)mc.getMock();
// set Mock Object behavior:
request.getParameter("username");
mc.setReturnValue("admin", 1);
request.getParameter("password");
mc.setReturnValue("1234", 1);
// ok, all behaviors are set!
mc.replay();
// now start test:
LoginServlet servlet = new LoginServlet();
try {
servlet.doPost(request, null);
fail("Not caught exception!");
}
catch(RuntimeException re) {
assertEquals("Login failed.", re.getMessage());
}
// verify:
mc.verify();
}
仔細觀(guān)察測試代碼,使用EasyMock來(lái)創(chuàng )建一個(gè)Mock對象需要首先創(chuàng )建一個(gè)MockControl:
MockControl mc = MockControl.createControl(HttpServletRequest.class);
然后,即可獲得MockControl創(chuàng )建的Mock對象:
HttpServletRequest request = (HttpServletRequest)mc.getMock();
下一步,我們需要“錄制”Mock對象的預期行為。在LoginServlet中,先后調用了request.getParameter("username")和request.getParameter("password")兩個(gè)方法,因此,需要在MockControl中設置這兩次調用后的指定返回值。我們期望返回的值為“admin”和“1234”:
request.getParameter("username"); // 期望下面的測試將調用此方法,參數為"username"
mc.setReturnValue("admin", 1); // 期望返回值為"admin",僅調用1次
request.getParameter("password"); // 期望下面的測試將調用此方法,參數為" password"
mc.setReturnValue("1234", 1); // 期望返回值為"1234",僅調用1次
緊接著(zhù),調用mc.replay(),表示Mock對象“錄制”完畢,可以開(kāi)始按照我們設定的方式運行,我們對LoginServlet進(jìn)行測試,并預期會(huì )產(chǎn)生一個(gè)RuntimeException:
LoginServlet servlet = new LoginServlet();
try {
servlet.doPost(request, null);
fail("Not caught exception!");
}
catch(RuntimeException re) {
assertEquals("Login failed.", re.getMessage());
}
由于本次測試的目的是檢查當用戶(hù)名和口令驗證失敗后,LoginServlet是否會(huì )拋出RuntimeException,因此,response對象對測試沒(méi)有影響,我們不需要模擬它,僅僅傳入null即可。
最后,調用mc.verify()檢查Mock對象是否按照預期的方法調用正常運行了。
運行JUnit,測試通過(guò)!表示我們的Mock對象正確工作了!
下一步,我們來(lái)測試當用戶(hù)名和口令匹配時(shí),LoginServlet應當把請求轉發(fā)給指定的RequestDispatcher。在這個(gè)測試用例中,我們除了需要HttpServletRequest Mock對象外,還需要模擬ServletContext和RequestDispatcher對象:
MockControl requestCtrl = MockControl.createControl(HttpServletRequest.class);
HttpServletRequest requestObj = (HttpServletRequest)requestCtrl.getMock();
MockControl contextCtrl = MockControl.createControl(ServletContext.class);
final ServletContext contextObj = (ServletContext)contextCtrl.getMock();
MockControl dispatcherCtrl = MockControl.createControl(RequestDispatcher.class);
RequestDispatcher dispatcherObj = (RequestDispatcher)dispatcherCtrl.getMock();
按照doPost()的語(yǔ)句順序,我們設定Mock對象指定的行為:
requestObj.getParameter("username");
requestCtrl.setReturnValue("admin", 1);
requestObj.getParameter("password");
requestCtrl.setReturnValue("123456", 1);
contextObj.getNamedDispatcher("dispatcher");
contextCtrl.setReturnValue(dispatcherObj, 1);
dispatcherObj.forward(requestObj, null);
dispatcherCtrl.setVoidCallable(1);
requestCtrl.replay();
contextCtrl.replay();
dispatcherCtrl.replay();
然后,測試doPost()方法,這里,為了讓getServletContext()方法返回我們創(chuàng )建的ServletContext Mock對象,我們定義一個(gè)匿名類(lèi)并覆寫(xiě)getServletContext()方法:
LoginServlet servlet = new LoginServlet() {
public ServletContext getServletContext() {
return contextObj;
}
};
servlet.doPost(requestObj, null);
最后,檢查所有Mock對象的狀態(tài):
requestCtrl.verify();
contextCtrl.verify();
dispatcherCtrl.verify();
運行JUnit,測試通過(guò)!
倘若LoginServlet的代碼有誤,例如,將context.getNamedDispatcher("dispatcher")誤寫(xiě)為 context.getNamedDispatcher("dispatcher2"),則測試失敗,JUnit報告:
junit.framework.AssertionFailedError:
Unexpected method call getNamedDispatcher("dispatcher2"):
getNamedDispatcher("dispatcher2"): expected: 0, actual: 1
getNamedDispatcher("dispatcher"): expected: 1, actual: 0
at ...
完整的LoginServletTest代碼如下: /**
* LoginServletTest.java
* Author: Liao Xue Feng,www.crackj2ee.com
*/
package com.crackj2ee.test.mock; import javax.servlet.*;
import javax.servlet.http.*; import org.easymock.*;
import junit.framework.TestCase; public class LoginServletTest extends TestCase {     public void testLoginFailed() throws Exception {
MockControl mc = MockControl.createControl(HttpServletRequest.class);
HttpServletRequest request = (HttpServletRequest)mc.getMock();
// set Mock Object behavior:
request.getParameter("username");
mc.setReturnValue("admin", 1);
request.getParameter("password");
mc.setReturnValue("1234", 1);
// ok, all behaviors are set!
mc.replay();
// now start test:
LoginServlet servlet = new LoginServlet();
try {
servlet.doPost(request, null);
fail("Not caught exception!");
}
catch(RuntimeException re) {
assertEquals("Login failed.", re.getMessage());
}
// verify:
mc.verify();
}     public void testLoginOK() throws Exception {
// create mock:
MockControl requestCtrl = MockControl.createControl(HttpServletRequest.class);
HttpServletRequest requestObj = (HttpServletRequest)requestCtrl.getMock();
MockControl contextCtrl = MockControl.createControl(ServletContext.class);
final ServletContext contextObj = (ServletContext)contextCtrl.getMock();
MockControl dispatcherCtrl = MockControl.createControl(RequestDispatcher.class);
RequestDispatcher dispatcherObj = (RequestDispatcher)dispatcherCtrl.getMock();
// set behavior:
requestObj.getParameter("username");
requestCtrl.setReturnValue("admin", 1);
requestObj.getParameter("password");
requestCtrl.setReturnValue("123456", 1);
contextObj.getNamedDispatcher("dispatcher");
contextCtrl.setReturnValue(dispatcherObj, 1);
dispatcherObj.forward(requestObj, null);
dispatcherCtrl.setVoidCallable(1);
// done!
requestCtrl.replay();
contextCtrl.replay();
dispatcherCtrl.replay();
// test:
LoginServlet servlet = new LoginServlet() {
public ServletContext getServletContext() {
return contextObj;
}
};
servlet.doPost(requestObj, null);
// verify:
requestCtrl.verify();
contextCtrl.verify();
dispatcherCtrl.verify();
}
}
總結:
雖然EasyMock可以用來(lái)模仿依賴(lài)對象,但是,它只能動(dòng)態(tài)模仿接口,無(wú)法模仿具體類(lèi)。這一限制正好要求我們遵循“針對接口編程”的原則:如果不針對接口,則測試難于進(jìn)行。應當把單元測試看作是運行時(shí)代碼的最好運用,如果代碼在單元測試中難于應用,則它在真實(shí)環(huán)境中也將難于應用??傊?,創(chuàng )建盡可能容易測試的代碼就是創(chuàng )建高質(zhì)量的代碼。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
什么是mock測試(3)
使用MOCK對象進(jìn)行單元測試 - zhangwenjun8045 - JavaEye技術(shù)網(wǎng)...
使用Mock Object進(jìn)行測試
單元測試相關(guān)的一些文檔
有效使用Mock編寫(xiě)java單元測試
單元測試-如何去mock對象
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久