HtmlUnit 的 WebClient 在第二个相同的 loadWebResponse() 调用上失败

发布于 2024-11-13 21:31:20 字数 5272 浏览 2 评论 0原文

我正在尝试在我正在为工作开发的网络应用程序中编写一个非常长且笨拙的“getPost”方法的测试。我使用 JUnitHtmlUnit 和 Jetty 的 ServletTester 来近似向 servlet 发送请求并接收响应。我已经设法让它大部分工作,但我遇到了问题。我正在尝试测试登录功能。如果用户成功登录,服务器应将一些包含用户信息的 JSON 发送回客户端。如果用户已经登录,服务器应该发送回“result”:“failure”和一条错误消息。

当我尝试测试第二个要求时,我的问题出现了。我可以成功登录,并获取正确的数据。但是,当我尝试再次发送请求时,它返回 404:未找到。我尝试将代码分解为不同的测试,但我必须能够调用登录两次才能测试第二个要求。 JUnit 文件中的后续测试运行得很好,并且 servlet 同时保持连接。我尝试提出第二个相同的请求,但也失败了。我在网上搜索过没有结果。简而言之,我很困惑。

以下是我正在处理的内容(不必要的代码已被删除):

//In MyFunServlet class:
private final static String USERID_ATTRIBUTENAME = "userid";
void doPost(HttpServletRequest request, HttpServletResponse response) {
    String action = request.getParameter("opt");
    final HttpSession session = request.getSession();

    if(action != null){
       Long userId = (Long)session.getAttribute(USERID_ATTRIBUTENAME);
       if(userId != null){
           //do stuffz
       } else {
           if(action.equals("login")) {
               User user = LoginUser(request, response);
               try{
                   JSONObject json = new JSONObject();
                   if(request.getAttribute("result") == "success"){
                       json.put("result", "success");
                       json.put("id", user.getId());
                       json.put("name", user.getName());
                   } else {
                       json.put("result", "failure");
                       json.put("message", request.getAttribute("message"));
                   }
                   SendJSONResponse(json, request, response);
               }catch(Exception e){
               }
            } else {
                System.out.print("Unknown opt: " + action);
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            }
        }
    }
}

private void LoginUser(HttpServletRequest request, HttpServletResponse response){
    final HttpSession session = request.getSession();
    User user = null;
    Long userId = (Long)session.getAttribute(USERID_ATTRIBUTENAME);
    if(userId != null){
        request.setAttribute("result", "failure");
        request.setAttribute("message", "The user is already logged in.");
    } else {
        final String email = request.getParameter("accountEmail");
        final String password = request.getParameter("accountPassword");
        if(email != null) {
            user = helperClass.magicallyGetUserByEmail(email);
            if(user != null){
                if(user.getPassword().equals(password)){
                    session.setAttribute(USERID_ATTRIBUTENAME, user.getId();
                    request.setAttribute("result", "success");
                }
            }
        } else {
           request.setAttribute("result", "failure");
        }
    }
    return user;
}

private void SendJSONResponse(JSONObject json, HttpServletRequest request,
                                HttpServletResponse response) {
    String contentStr = json.toString();
    response.setContentType("application/json");
    response.setStatus( HttpServletResponse.SC_OK);
    response.setContentLength(contentStr.length());
    response.getWriter().print(contentStr);
    response.flushBuffer();
}

出于参考目的,该文件有 1084 行长。 doPost 方法大约有 900 个。免责声明:这不是我的代码。不是我写的。我只需要测试一下。 现在进行测试:

//In MyFunServletTest.java:
//using JUnit 4

public class MyFunServletTest {
    static ServletTester tester;
    static String baseUrl;

    WebClient webClient = new WebClient();

    User user;
    WebRequest loginRequest;

    @BeforeClass
    public static void initClass(){
        tester = new ServletTester;
        tester.setContextPath("/");
        tester.addServlet(MyFunServlet.class, "/fun.service");
        baseUrl = tester.createSocketConnector(true);
        tester.start();
    }

    @AfterClass
    public static void cleanClass() {
        tester.stop();
    }

    @Before
    public void preTest(){
        //taking values from our magical test user
        user = new User();
        user.setEmail("[email protected]");
        user.setPassword("secure");

        loginRequest = new WebRequest(baseUrl + "/fun.service", HttpMethod.POST);
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new NameValuePair("opt","login"));
        params.add(new NameValuePair("accountEmail", user.getEmail());
        params.add(new NameValuePair("accountPassword", user.getPassword());
        loginRequest.setRequestParameters(params);

    }

    @Test
    public void testLogin() {
        WebResponse response = webClient.loadWebResponse(loginRequest);
        JSONObject responseJSON = new JSONObject(response.getContentAsString());

        //this test passes
        assertEquals("success", responseJSON.getString("result"));

        response = webClient.loadWebResponse(loginRequest);

        //this test fails
        assertTrue(404 != response.getStatusCode());

        //this then causes an error, as response.getContentAsString() is null.
        esponseJSON = new JSONObject(response.getContentAsString());
    }
}

有帮助吗?我哪里遗漏了什么?

谢谢。

I'm attempting to write tests for a very long and kludgy "getPost" method in a webapp I'm working on for my job. I'm using JUnit, HtmlUnit, and Jetty's ServletTester to approximate sending a request to a servlet and receiving a response. I've managed to get it mostly working, but I'm having a problem. I'm trying to test the login functionality. If the user logs in successfully, the server should send some JSON back to the client with the user's information. If the user is already logged in, the server should send back "result": "failure" and an error message.

My problem comes when I try to test the second requirement. I can log in successfully, and get the correct data back. However, when I try to send the request again, it returns 404: not found. I tried breaking the code up into different tests, but I have to be able to call login twice in order to test the second requirement. Later tests in the JUnit file run just fine, and the servlet is staying connected the same time. I tried making a second, identical request, but that also failed. I've searched the internet to no avail. In short, I'm stumped.

Here's what I'm working with (unnecessary code has been edited out):

//In MyFunServlet class:
private final static String USERID_ATTRIBUTENAME = "userid";
void doPost(HttpServletRequest request, HttpServletResponse response) {
    String action = request.getParameter("opt");
    final HttpSession session = request.getSession();

    if(action != null){
       Long userId = (Long)session.getAttribute(USERID_ATTRIBUTENAME);
       if(userId != null){
           //do stuffz
       } else {
           if(action.equals("login")) {
               User user = LoginUser(request, response);
               try{
                   JSONObject json = new JSONObject();
                   if(request.getAttribute("result") == "success"){
                       json.put("result", "success");
                       json.put("id", user.getId());
                       json.put("name", user.getName());
                   } else {
                       json.put("result", "failure");
                       json.put("message", request.getAttribute("message"));
                   }
                   SendJSONResponse(json, request, response);
               }catch(Exception e){
               }
            } else {
                System.out.print("Unknown opt: " + action);
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            }
        }
    }
}

private void LoginUser(HttpServletRequest request, HttpServletResponse response){
    final HttpSession session = request.getSession();
    User user = null;
    Long userId = (Long)session.getAttribute(USERID_ATTRIBUTENAME);
    if(userId != null){
        request.setAttribute("result", "failure");
        request.setAttribute("message", "The user is already logged in.");
    } else {
        final String email = request.getParameter("accountEmail");
        final String password = request.getParameter("accountPassword");
        if(email != null) {
            user = helperClass.magicallyGetUserByEmail(email);
            if(user != null){
                if(user.getPassword().equals(password)){
                    session.setAttribute(USERID_ATTRIBUTENAME, user.getId();
                    request.setAttribute("result", "success");
                }
            }
        } else {
           request.setAttribute("result", "failure");
        }
    }
    return user;
}

private void SendJSONResponse(JSONObject json, HttpServletRequest request,
                                HttpServletResponse response) {
    String contentStr = json.toString();
    response.setContentType("application/json");
    response.setStatus( HttpServletResponse.SC_OK);
    response.setContentLength(contentStr.length());
    response.getWriter().print(contentStr);
    response.flushBuffer();
}

For reference purposes, this file is 1084 lines long. The doPost method is about 900 of those. Disclaimer: this is not my code. I did not write it. I only have to test it.
Now for the test:

//In MyFunServletTest.java:
//using JUnit 4

public class MyFunServletTest {
    static ServletTester tester;
    static String baseUrl;

    WebClient webClient = new WebClient();

    User user;
    WebRequest loginRequest;

    @BeforeClass
    public static void initClass(){
        tester = new ServletTester;
        tester.setContextPath("/");
        tester.addServlet(MyFunServlet.class, "/fun.service");
        baseUrl = tester.createSocketConnector(true);
        tester.start();
    }

    @AfterClass
    public static void cleanClass() {
        tester.stop();
    }

    @Before
    public void preTest(){
        //taking values from our magical test user
        user = new User();
        user.setEmail("[email protected]");
        user.setPassword("secure");

        loginRequest = new WebRequest(baseUrl + "/fun.service", HttpMethod.POST);
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new NameValuePair("opt","login"));
        params.add(new NameValuePair("accountEmail", user.getEmail());
        params.add(new NameValuePair("accountPassword", user.getPassword());
        loginRequest.setRequestParameters(params);

    }

    @Test
    public void testLogin() {
        WebResponse response = webClient.loadWebResponse(loginRequest);
        JSONObject responseJSON = new JSONObject(response.getContentAsString());

        //this test passes
        assertEquals("success", responseJSON.getString("result"));

        response = webClient.loadWebResponse(loginRequest);

        //this test fails
        assertTrue(404 != response.getStatusCode());

        //this then causes an error, as response.getContentAsString() is null.
        esponseJSON = new JSONObject(response.getContentAsString());
    }
}

Help? Where am I missing something?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

楠木可依 2024-11-20 21:31:20

由于无法自己运行测试,我只能提供一些方法:

  • 尝试创建两个 JSONObject 对象来分别存储两个响应,并比较两个(打印它们或使用调试器),看看是否有任何东西看起来很奇怪。

  • 如果这没有告诉您任何信息,请创建两个单独的相同请求实例并使用每个实例。

  • 然后尝试跟踪对 loadWebResponse 的调用,以准确查看正在请求的 URL(提高日志级别也可能会告诉您这一点)。

如果 404 正确,那么第二个请求在某种程度上被破坏了,但问题是在哪里。

Without the ability to run the test myself, I can only offer some approaches:

  • Try creating two JSONObject objects to store the two responses separately, and compare the two (either print them or using the debugger), see if anything looks odd there.

  • If that doesn't tell you anything, create two separate identical request instances and use each.

  • Then try tracing through the call to loadWebResponse to see exactly what URL is being requested (cranking up the log level might tell you this, too).

If the 404 is correct, then the second request is somehow being mangled, but the question would be WHERE.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文