因断言而没有关闭响应

时间:2017-03-14 14:35:55

标签: java jersey

我有以下测试:

    @After
    public void tear_down() {
        remove_test_data();
    }

    private void remove_test_data() {
        delete_product("product1").close()
    }

    @Test
    public void test_crud() {
        Product product = product_factory("product1");

        Response response = post_product(product);
        assertThat(response.getStatus(), is(201));
        response.close();

        response = get_product(product);
        assertThat(response.getStatus(), is(200));
        Product gottenProduct = response.readEntity(ProductList.class);
        response.close();
    }

    private Response get_product(Product product) {
        return provider
                .target()
                .path(product.getName())
                .request(MediaType.APPLICATION_JSON)
                .get();

        return response;
    }

但是,如果第二个断言失败(assertThat(response.getStatus(), is(200))),则不会为此响应调用response.close()。这意味着我在拆解时遇到以下异常:

java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated.
Make sure to release the connection before allocating another one.
    at org.apache.http.util.Asserts.check(Asserts.java:34)
    at org.apache.http.impl.conn.BasicClientConnectionManager.getConnection(BasicClientConnectionManager.java:160)
    at org.apache.http.impl.conn.BasicClientConnectionManager$1.getConnection(BasicClientConnectionManager.java:142)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:423)
    at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:863)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
    at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:283)

我应该怎么做以避免这个问题?

1 个答案:

答案 0 :(得分:1)

这是一个简单的try-finally用例,例如:

try {

 // do work here

} finally { 
   if (response != null) response.close()
}

或者,您可能需要查看Junit为测试管理提供的After注释。这些通常用于清理操作。

至于你的上一个问题,你可以在做其他任何事情之前尝试关闭你的回复。但是,请阅读以下文档:

/**
     * Close the underlying message entity input stream (if available and open)
     * as well as releases any other resources associated with the response
     * (e.g. {@link #bufferEntity() buffered message entity data}).
     * <p>
     * This operation is idempotent, i.e. it can be invoked multiple times with the
     * same effect which also means that calling the {@code close()} method on an
     * already closed message instance is legal and has no further effect.
     * </p>
     * <p>
     * The {@code close()} method should be invoked on all instances that
     * contain an un-consumed entity input stream to ensure the resources associated
     * with the instance are properly cleaned-up and prevent potential memory leaks.
     * This is typical for client-side scenarios where application layer code
     * processes only the response headers and ignores the response entity.
     * </p>
     * <p>
     * Any attempts to manipulate (read, get, buffer) a message entity on a closed response
     * will result in an {@link IllegalStateException} being thrown.
     * </p>
     *
     * @throws ProcessingException if there is an error closing the response.
     * @since 2.0
     */

这意味着,如果您关闭响应,则可能会遇到不同的错误。例如,您提供的测试如下所示:

        response = get_product(product);
        assertThat(response.getStatus(), is(200));
        Product gottenProduct = response.readEntity(ProductList.class);
        response.close();

如果在阅读实体之前关闭了您的响应,则实体流将被关闭,这将为您抛出异常。

所以,我认为,如果你想在不使用JUnit注释的代码中正确关闭它,那么你应该使用try-finally