java - 如何创建 ServletContext 的模拟属性?

标签 java unit-testing servlets mocking mockito

我有在数据库中添加用户的 Servlet。 Servlet 使用模块实例来处理数据库,他的别名是 DBJoint。 Servlet 从 ServletContext 获取 DBJoint 的实例。

@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 并通过键 "db" 获取 DBJoint

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(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/

相关文章:

java - 没有应用可以处理此操作 Google Duo

java - 与 2 个对象进行 block 同步不起作用

java - 使用 RSE 通过 Eclipse 将远程源作为 Java 项目 check out

php - 您可以在回调中使用 $this 来获取 phpunit 中模拟类的 protected 属性吗?

java - sendRedirect URL 在 JBOSS 7.2 中附加了根 url

java - 除括号中的空格之外的所有空格拆分字符串

内容为CountDownTimer类的Android单元测试方法

unit-testing - Ruby - 使用 TDD/BDD 进行软件测试的实用方法

css - 复选框控制 servlet 中所有相同的 css 类 ID 颜色

javascript - 如何使用从 Servlet 发送并由 JavaScript 通过 Jquery 接收的数据来更改网页内容?