【问题标题】:Could current approach to TDD in Servlets be optimized?可以优化 Servlet 中当前的 TDD 方法吗?
【发布时间】:2014-08-19 10:15:08
【问题描述】:

当前的方法是在 ServletTest 中创建 HTML,运行测试,更改 Servlet,直到测试变为绿色。然而,感觉这种在 Servlet 中进行 TDD 的方法比 TDD 普通 Java 类更狡猾且更耗时,因为在 ServletTest 中创建的 HTML 大部分被复制到 Servlet 并随后更改了格式(例如删除反斜杠)而不是在普通 Java 类的测试中测试输出并在 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>");
}

【问题讨论】:

  • 我认为主要问题是您一开始就以这种方式构建 html 页面。你为什么不使用 JSF 或类似的技术呢?
  • 这是一个集成测试。您正在模拟浏览器。您的 HTML 应该使用一些 模板引擎模板 中生成。该引擎将 data 作为输入。您应该测试生成该 data 而不是 HTML 的方法。
  • @Keppil 我正在关注these steps 来实现 JSF。但是,The import javax.faces cannot be resolved。我正在使用 jdk8 并试图解决这个问题,因为 JSF 回答了这个问题。谢谢你的建议。
  • JSF 不是 Java SE 的一部分。当然你会得到一个编译错误。
  • 导入正确的库后即可使用

标签: java html servlets tdd java-8


【解决方案1】:

我认为这里的主要问题是您通过手动将各种字符串中的 html 元素组合在一起来构建 html 页面。正如您所经历的,这会导致代码难以测试和维护。

尝试使用 JSF 或一些类似的技术。这将使您能够只专注于 Java 端的功能,这更容易测试。

【讨论】:

    猜你喜欢
    • 2013-05-31
    • 1970-01-01
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-04
    • 2013-03-05
    相关资源
    最近更新 更多