2017-06-19 68 views
1

我有在數據庫中添加用戶的Servlet。 Servlet使用模塊的實例來處理數據庫,他的別名爲DBJoint。並且Servlet從ServletContext獲得DBJoint的實例。如何創建ServletContext的mock屬性?

@WebListener 
public class ContextListener implements ServletContextListener { 
    @Override 
    public void contextInitialized(ServletContextEvent servletContextEvent) { 
     final ServletContext servletContext = 
       servletContextEvent.getServletContext(); 

     final DBJoint joint = new DBJointHandler(
       "database_scripts", 
       "authentication_database"); 

     servletContext.setAttribute("db", joint); 
    } 
} 

而在當我需要與數據庫我叫ServletContext和關鍵"db"得到DBJoint工作每個servlet。

public class AddUserServlet extends HttpServlet { 

    @Override 
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException { 

     req.setCharacterEncoding("UTF8"); 

     try { 

      final boolean success = addUserInDatabase(req); 

      if (success) req.setAttribute("serverAnswer", EDIT_SUCCESS.get()); 
      else req.setAttribute("serverAnswer", ERR_UNIQUE_L_P.get()); 

      req.getRequestDispatcher(ANSWER.get()) 
        .forward(req, resp); 

     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
    } 

    /** 
    * Addition user in database. 
    * 
    * @return true if addition success, else false. 
    */ 
    private boolean addUserInDatabase(final HttpServletRequest req) 
      throws SQLException { 

     final User user = getUserFromRequest(req); 
     return getDatabaseExecutor().addUserAndGetSuccess(user); 
    } 

    /** 
    * Extracts user's data from HttpServletRequest. 
    * 
    * @return user from request. 
    */ 
    private User getUserFromRequest(final HttpServletRequest req) { 
     return new User(
       req.getParameter("name"), 
       req.getParameter("login"), 
       req.getParameter("password"), 
       req.getParameter("email"), 
       req.getParameter("role") 
     ); 
    } 

    /** 
    * Get executor database requests. 
    */ 
    private ScriptExecutor getDatabaseExecutor() throws SQLException { 
     final DBJoint db = (DBJoint) getServletContext().getAttribute("db"); 
     return db.getDBScriptExecutor(); 
    } 
} 

我需要測試我的Servlet,並使用模仿對象,而不是原來的對象:

在這個測試中,我嘗試驗證什麼身體的doPost調用ADDUSER(用戶U)的數據庫腳本的執行。但獲得NPE。

@Test 
public void whenUserAddThenAddUserCall() throws ServletException, IOException, SQLException { 

    final AddUserServlet servlet = new AddUserServlet(); 

    //mock http. 
    HttpServletRequest request = mock(HttpServletRequest.class); 
    HttpServletResponse response = mock(HttpServletResponse.class); 

    User user = new User("name", "login", "password", "email"); 

    //mock database. 
    ScriptExecutor executor = mock(ScriptExecutor.class); 

    DBJoint joint = mock(DBJointHandler.class); 
    when(joint.getDBScriptExecutor()).thenReturn(executor); 


    final ServletContext context = request.getServletContext(); 
    //In this place I get NPE but why? 
    context.setAttribute("db", joint); 

    servlet.doPost(request, response); 

    verify(executor).addUser(user); 
} 

爲什麼我有NullPointerException?如何測試這個課程?謝謝!

回答

0

您需要包括這些以及

ServletContext context = mock(ServletContext .class) 
when(request.getServletContext()).thenReturn(context); 
0

您正在致電request.getServletContext()request對象這是一個模擬。

模擬對象不提供真正的方法實現。而不是真正的getServletContext()實現,該方法的stubbed版本被稱爲返回null。

一個模擬應該告訴它需要返回什麼時調用一個方法,你需要定義行爲就像你爲DBJoinHandler模​​擬。

爲了解決NPE,做這樣的事情:

when(request.getServletContext()).thenReturn(context); 

其中context可能是一個ServletContext模擬。

+0

'時(executor.addUserAndGetSuccess(用戶))thenReturn(真);'我得到'IllegalStateException異常:ServletConfig類一直沒有initialized'我AddUserServlet調用'getDatabaseExecutor ()',這是失敗的。我需要模擬ServletContext,因爲'getDatabaseExecutor()'將被調用。 – Pavel

+0

當你在'request'模擬中調用getServletContext()方法時,你需要定義行爲。試試這樣:'when(request.getServletContext())。thenReturn(mock(ServletContext.class));' –