HtmlUnit的WebClient在第二次相同的loadWebResponse()调用时失败

时间:2011-06-03 15:16:00

标签: java servlets junit htmlunit

我正在尝试在我正在为我的工作工作的webapp中编写一个非常长且具有kludgy“getPost”方法的测试。我正在使用JUnitHtmlUnit和Jetty的ServletTester来近似向servlet发送请求并接收响应。我设法让它主要工作,但我遇到了问题。我正在尝试测试登录功能。如果用户成功登录,服务器应该使用用户的信息将一些JSON发送回客户端。如果用户已登录,则服务器应发回“结果”:“失败”和错误消息。

当我尝试测试第二个要求时,我的问题出现了。我可以成功登录,并获取正确的数据。但是,当我尝试再次发送请求时,它返回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("blah@blah.com");
        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());
    }
}

帮助?我在哪里错过了什么?

感谢。

1 个答案:

答案 0 :(得分:0)

如果没有自己运行测试的能力,我只能提供一些方法:

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

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

  • 然后尝试通过对loadWebResponse的调用来查看确切的URL请求(启动日志级别也可以告诉您这一点)。

如果404是正确的,那么第二个请求会以某种方式被破坏,但问题是WHERE。