我有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 );
您正在模拟request
对象上调用request.getServletContext()
。
模拟对象不提供真正的方法实现。而不是真正的getServletContext((实现,该方法的存根版本称为返回null。
当调用一个方法时,应该告诉模拟需要返回什么,你需要定义行为,就像你对DBJoinHandler模拟所做的那样。
要解决 NPE,请执行以下操作:
when(request.getServletContext()).thenReturn(context);
其中context
可以是 ServletContext 模拟。