<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    計算機學習積累

    ----轉載有理,轉載是想研究,想研究才會看,看了才會有感想,轉載后我有時會寫一些自己的感受
    數據加載中……

    EasyMock的簡單使用(摘)


    xp開發的一個利器--EasyMock。
    EasyMock是一種
    動態生成模仿對象以便應用于單元測試的工具,有了它可擺脫容器進行單元測試了。
    它的使用很簡單,下面一個簡單登陸驗證的例子:
    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. "
    );
    }
    }
    }

    這個 Servlet 實現簡單的用戶驗證的功能,若用戶名和口令匹配“ admin ”和“ 123456 ”,則請求被轉發到指定的 dispatcher 上,否則,直接拋出 RuntimeException

    為了測試 doPost() 方法,我們需要模擬 HttpServletRequest ServletContext RequestDispatcher 對象,以便脫離 J2EE 容器來測試這個 Servlet

    我們建立 TestCase ,名為 LoginServletTest

    public ? class ?LoginServletTest? extends ?TestCase?{

    }

    我們首先測試當用戶名和口令驗證失敗的情形,演示如何使用EasyMock來模擬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();

    }

    仔細觀察測試代碼,使用 EasyMock 來創建一個 Mock 對象需要首先創建一個 MockControl
    MockControl?mc? = ?MockControl.createControl(HttpServletRequest. class );

    然后,即可獲得 MockControl 創建的 Mock 對象:
    HttpServletRequest?request? = ?(HttpServletRequest)mc.getMock();

    下一步,我們需要“錄制” Mock 對象的預期行為。在 LoginServlet 中,先后調用了 request.getParameter("username") request.getParameter("password") 兩個方法,因此,需要在 MockControl 中設置這兩次調用后的指定返回值。我們期望返回的值為“ admin ”和“ 1234 ”:
    request.getParameter( " username " );? // ?期望下面的測試將調用此方法,參數為"username"
    mc.setReturnValue( " admin " ,? 1 );? // ?期望返回值為"admin",僅調用1次

    request.getParameter(
    " password " );? // ?期望下面的測試將調用此方法,參數為"?password"

    mc.setReturnValue(
    " 1234 " ,? 1 );? // ?期望返回值為"1234",僅調用1次
    緊接著,調用 mc.replay() ,表示 Mock 對象“錄制”完畢,可以開始按照我們設定的方式運行,我們對 LoginServlet 進行測試,并預期會產生一個 RuntimeException
    LoginServlet?servlet? = ? new ?LoginServlet();

    try
    ?{

    servlet.doPost(request,?
    null
    );

    fail(
    " Not?caught?exception! "
    );

    }

    catch
    (RuntimeException?re)?{

    assertEquals(
    " Login?failed. "
    ,?re.getMessage());

    }

    由于本次測試的目的是檢查當用戶名和口令驗證失敗后, LoginServlet 是否會拋出 RuntimeException ,因此, response 對象對測試沒有影響,我們不需要模擬它,僅僅傳入 null 即可。

    最后,調用 mc.verify() 檢查 Mock 對象是否按照預期的方法調用正常運行了。

    運行 JUnit ,測試通過!表示我們的 Mock 對象正確工作了!
    ? 下一步,我們來測試當用戶名和口令匹配時,LoginServlet應當把請求轉發給指定的RequestDispatcher。在這個測試用例中,我們除了需要HttpServletRequest Mock對象外,還需要模擬ServletContextRequestDispatcher對象:


    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()的語句順序,我們設定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() 方法返回我們創建的 ServletContext Mock 對象,我們定義一個匿名類并覆寫 getServletContext() 方法:
    LoginServlet?servlet? = ? new ?LoginServlet()?{

    public
    ?ServletContext?getServletContext()?{

    return
    ?contextObj;

    }

    };

    servlet.doPost(requestObj,?
    null
    );

    最后,檢查所有Mock對象的狀態:

    requestCtrl.verify();

    contextCtrl.verify();

    dispatcherCtrl.verify();

    運行 JUnit ,測試通過!

    倘若 LoginServlet 的代碼有誤,例如,將 context.getNamedDispatcher("dispatcher") 誤寫為 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 ...

    總結:

    雖然 EasyMock 可以用來模仿依賴對象,但是,它只能動態模仿接口,無法模仿具體類。這一限制正好要求我們遵循“針對接口編程”的原則:如果不針對接口,則測試難于進行。應當把單元測試看作是運行時代碼的最好運用,如果代碼在單元測試中難于應用,則它在真實環境中也將難于應用。總之,創建盡可能容易測試的代碼就是創建高質量的代碼。

    ? 現在,easymock可以模仿類了,以下是在springside摘的:

    // 設定BookManager?MockObject
    ????????bookManagerMockControl? = ?MockClassControl.createControl(BookManager. class );
    ????????bookManagerMock?
    =
    ?(BookManager)?bookManagerMockControl.getMock();
    ????????controller.setBookManager(bookManagerMock);
    ???????
    // 錄制getAllBook()和getCategorys方法的期望值

    ????????bookManagerMock.getAllBook();
    ????????bookManagerMockControl.setReturnValue(
    new
    ?ArrayList());
    ????????bookManagerMockControl.replay();
    ????????
    // 執行操作

    ????????mv? = ?controller.handleRequest(request,?response);
    // 驗證結果?????????

    ????????assertModelAttributeAvailable(mv,? " books " );


    posted on 2007-03-02 09:13 freebird 閱讀(554) 評論(0)  編輯  收藏 所屬分類: java

    主站蜘蛛池模板: 巨胸喷奶水视频www免费视频| 亚洲AV无码AV男人的天堂不卡| 午夜小视频免费观看| 国产色爽免费无码视频| 视频一区在线免费观看| 亚洲视频无码高清在线| 亚洲天堂久久精品| 亚洲色婷婷六月亚洲婷婷6月 | 亚洲精品在线观看视频| 中文字幕一精品亚洲无线一区| 免费一级毛片免费播放| 免费A级毛片无码免费视| 亚洲一区二区免费视频| 99在线免费观看视频| 免费A级毛片av无码| 99爱在线观看免费完整版| 亚洲免费视频在线观看| 91成人在线免费观看| 国产福利视精品永久免费| 亚洲免费网站观看视频| 99精品国产免费久久久久久下载 | 亚洲一卡二卡三卡| 亚洲sss综合天堂久久久| 亚洲性无码AV中文字幕| 西西人体大胆免费视频| 国产成人免费AV在线播放 | 丝袜捆绑调教视频免费区| 久久久久av无码免费网| 日本久久久免费高清| 国产亚洲精aa成人网站| 亚洲av无码专区在线| 一区二区三区免费视频播放器| 小草在线看片免费人成视久网| 日韩免费精品视频| 黑人大战亚洲人精品一区| 亚洲依依成人精品| GOGOGO免费观看国语| 99精品全国免费观看视频| 久久久久亚洲AV无码网站| 日本激情猛烈在线看免费观看| 永久黄色免费网站|