我有Servlet,可以在数据库中添加用户。 Servlet使用模块的实例与别名为DBJoint的数据库一起使用。然后Servlet从DBJoint获取ServletContext的实例。

@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);
    }
}


在每个Servlet中,当我需要使用数据库时,我调用ServletContext并通过键DBJoint获取"db"

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,并使用模拟对象代替原始对象:

在此测试中,我尝试验证数据库脚本执行程序中dobody调用addUser(User 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?如何测试这堂课?谢谢!

最佳答案

您也需要包括这些

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

关于java - 如何创建ServletContext的模拟属性?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44638809/

10-10 14:04