Could current approach to TDD in Servlets be optimized?

人走茶凉 提交于 2019-12-23 02:30:17

问题


The current approach is creating HTML in a ServletTest, run the test, change the Servlet until the test turns into green. However, it feels like that this approach to TDD in Servlets is devious and more time-consuming than TDD ordinary Java classes as HTML created in the ServletTest is copied to the Servlet for the most part and subsequently changed regarding the format (e.g. removing backslashes) instead of testing the output in a Test for ordinary Java Classes and writing most of the code in the main.

ServletTest:

HttpServletRequest mockedHttpServletRequest = mock(HttpServletRequest.class);
HttpServletResponse mockedHttpServletResponse = mock(HttpServletResponse.class);
HttpSession mockedHttpSession = mock(HttpSession.class);

StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);

private final String doGetHtmlStringPartOne = "<html><body><table>"
        + "<tr><td><h1>";
private final String doGetHtmlStringPartTwo = "<\\/h1><\\/td>"
        + "<form method=\"post\">"
        + "<input type=\"hidden\" name=\"randomDigitRange\" value=\"1\" \\/>"
        + "<input type=\"hidden\" name=\"randomMathematicalOperator\""
        + " value=\"1\" \\/><input type=\"hidden\" name=\"fractionBoolean\""
        + " value=\"";

private final String doGetHtmlStringPartThree = "<td><input type=\"radio\" name=\"userInput\" value=\"(\\d)+.(\\d)+\">(\\d)+(\\s\\/\\s(\\d)+)?<\\/td>";

private final String doGetHtmlStringPartFour = "<\\/tr><tr><td>"
        + "<input type=\"submit\" value=\"Submit\" "
        + "onclick='this.form.action=\"ToBeDefinedServlet\";' \\/>"
        + "<\\/td><\\/tr><\\/table><\\/form><\\/body><\\/html>"
        + "<form action=\"\\/tobedefinedservlet\">"
        + "<input type=\"submit\" value=\"Home\"><\\/form>";

@Test
public void testBooleanFractionTrue() throws IOException, ServletException {
    mockDoGet();
    assertTrue(stringWriter.getBuffer().toString().trim().matches(expectedDoGetHtmlString("1 \\/ 1 \\+ 1 \\/ 1", true)));
}

public String expectedDoGetHtmlString(String assignment,
        Boolean fractionBoolean) {
    return doGetHtmlStringPartOne + assignment + doGetHtmlStringPartTwo
            + "" + fractionBoolean + "" + "\" \\/>" + "\\n"
            + doGetHtmlStringPartThree + "\\n" + doGetHtmlStringPartFour;
}

public void mockDoGet() throws IOException, ServletException {
    when(mockedHttpServletRequest.getSession()).thenReturn(
            mockedHttpSession);
    when(mockedHttpServletResponse.getWriter()).thenReturn(printWriter);
    when(mockedHttpServletRequest.getParameter("fractionBoolean"))
            .thenReturn("true");
    when(mockedHttpServletRequest.getParameter("randomDigitRange"))
            .thenReturn("1");
    when(
            mockedHttpServletRequest
                    .getParameter("randomMathematicalOperator"))
            .thenReturn("1");
    when(mockedHttpServletRequest.getSession()).thenReturn(
            mockedHttpSession);
    new ToBeDefinedServlet().doGet(mockedHttpServletRequest,
            mockedHttpServletResponse);
}

Servlet:

protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    calculation.setFractionBoolean(Boolean.parseBoolean(request
            .getParameter("fractionBoolean")));
    calculation.setAssignment(Double.parseDouble(request
            .getParameter("randomDigitRange")), Double.parseDouble(request
            .getParameter("randomMathematicalOperator")));
    PrintWriter out = response.getWriter();

    out.println("<html><body><table>"
            + "<tr><td><h1>"
            + calculation.getAssignment()
            + "</h1></td>"
            + "<form method=\"post\">"
            + "<input type=\"hidden\" name=\"randomDigitRange\" value=\""
            + request.getParameter("randomDigitRange")
            + "\" />"
            + "<input type=\"hidden\" name=\"randomMathematicalOperator\" value=\""
            + request.getParameter("randomMathematicalOperator") + "\" />"
            + "<input type=\"hidden\" name=\"fractionBoolean\" value=\""
            + request.getParameter("fractionBoolean") + "\" />");

    for (double possibleAnswer : calculation.getPossibleAnswersArray()) {
        String possibleAnswerFormat = Boolean.parseBoolean(request
                .getParameter("fractionBoolean")) == true ? ""
                + new Fraction(possibleAnswer) + "" : "" + possibleAnswer
                + "";

        out.println("<td><input type=\"radio\" name=\"userInput\" value=\""
                + possibleAnswer + "\">" + possibleAnswerFormat + "</td>");
    }

    out.println("</tr>"
            + "<tr><td><input type=\"submit\" value=\"Submit\" "
            + "onclick='this.form.action=\"ToBeDefinedServlet\";' /></td>"
            + "</tr></table></form></body></html>"
            + "<form action=\"/tobedefinedservlet\"><input type=\"submit\" value=\"Home\"></form>");
}

回答1:


I think the main problem here is that you are building your html page by manually putting the html elements together from various strings. As you have experienced, this leads to code that is hard to test and maintain.

Try using JSF or some simliar technique instead. This will enable you to focus only on the functionality on the Java side, which is much easier to test.



来源:https://stackoverflow.com/questions/24466451/could-current-approach-to-tdd-in-servlets-be-optimized

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!