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

Java HtmlUnit';s WebClient在第二次相同的loadWebResponse()调用时失败,java,servlets,junit,htmlunit,Java,Servlets,Junit,Htmlunit,我正试图在一个为我的工作而开发的webapp中为一个非常长且笨拙的“getPost”方法编写测试。我正在使用JUnit、HtmlUnit和Jetty的ServletTester来近似地向servlet发送请求并接收响应。我已经设法让它大部分工作,但我有一个问题。我正在测试登录功能。如果用户成功登录,服务器应将一些JSON连同用户信息发送回客户端。如果用户已登录,服务器应返回“结果”:“失败”和错误消息 当我尝试测试第二个需求时,我的问题就出现了。我可以成功登录,并获取正确的数据。但是,当我再次尝

我正试图在一个为我的工作而开发的webapp中为一个非常长且笨拙的“getPost”方法编写测试。我正在使用JUnit、HtmlUnit和Jetty的ServletTester来近似地向servlet发送请求并接收响应。我已经设法让它大部分工作,但我有一个问题。我正在测试登录功能。如果用户成功登录,服务器应将一些JSON连同用户信息发送回客户端。如果用户已登录,服务器应返回“结果”:“失败”和错误消息

当我尝试测试第二个需求时,我的问题就出现了。我可以成功登录,并获取正确的数据。但是,当我再次尝试发送请求时,它返回404:notfound。我尝试将代码分成不同的测试,但是为了测试第二个需求,我必须能够调用login两次。JUnit文件中的后续测试运行良好,同时servlet保持连接。我试着提出第二个相同的请求,但也失败了。我在互联网上搜索了一下,结果一无所获。简言之,我被难住了

以下是我的工作内容(不必要的代码已被删除):

出于参考目的,此文件的长度为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());
    }
}
//在MyFunServletTest.java中:
//使用JUnit4
公共类MyFunServletTest{
静态伺服测试仪;
静态字符串baseUrl;
WebClient WebClient=新的WebClient();
用户;
网络请求登录请求;
@课前
公共静态void initClass(){
测试仪=新的ServletTester;
tester.setContextPath(“/”);
addServlet(MyFunServlet.class,“/fun.service”);
baseUrl=tester.createSocketConnector(true);
tester.start();
}
@下课
公共静态类(){
tester.stop();
}
@以前
公开无效预测试(){
//从我们神奇的测试用户那里获取值
user=新用户();
user.setEmail(“blah@blah.com");
user.setPassword(“安全”);
loginRequest=newWebRequest(baseUrl+“/fun.service”,HttpMethod.POST);
List params=new ArrayList();
参数添加(新的NameValuePair(“opt”、“login”);
添加(新的NameValuePair(“accountEmail”,user.getEmail());
添加(新的NameValuePair(“accountPassword”,user.getPassword());
loginRequest.setRequestParameters(参数);
}
@试验
公共void testLogin(){
WebResponse=webClient.loadWebResponse(loginRequest);
JSONObject responseJSON=新的JSONObject(response.getContentAsString());
//这个测试通过了
assertEquals(“成功”,responseJSON.getString(“结果”);
response=webClient.loadWebResponse(loginRequest);
//这个测试失败了
assertTrue(404!=response.getStatusCode());
//这会导致一个错误,因为response.getContentAsString()为null。
esponseJSON=newJSONObject(response.getContentAsString());
}
}
救命啊?我哪里漏了什么


谢谢。

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

  • 尝试创建两个
    JSONObject
    对象来分别存储这两个响应,并比较这两个响应(打印它们或使用调试器),查看是否有任何异常

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

  • 然后尝试通过调用
    loadWebResponse
    进行跟踪,以准确查看请求的URL(启动日志级别也可能会告诉您这一点)


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

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

  • 尝试创建两个
    JSONObject
    对象来分别存储这两个响应,并比较这两个响应(打印它们或使用调试器),查看是否有任何异常

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

  • 然后尝试通过调用
    loadWebResponse
    进行跟踪,以准确查看请求的URL(启动日志级别也可能会告诉您这一点)


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

另一个尝试是将testLogin()简化为第一个成功的测试,然后将其复制为testLogin2()或者诸如此类。如果在单独的测试方法中登录两次有效,那么我会认为您的原始请求/响应对象中发生了一些变化。但是,如果第二次登录失败,那么我会怀疑测试中的站点存在问题。另一个尝试是减少testLogin()仅复制成功的第一个测试,然后将其复制为testLogin2()或类似的内容。如果在单独的测试方法中登录两次有效,则我认为您的原始请求/响应对象发生了变化。但是,如果第二次登录失败,则我会怀疑测试中的站点有问题。
//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());
    }
}