0

我有一些使用 HttpURLConnection 来执行 RESTful API 的自动化测试。

我的部分代码(如下)断言响应返回某个 HTTP 响应代码。我期待 HTTP 206 响应,但 getResponseCode 始终返回 200。但是,如果我直接使用 curl 访问 url,我会得到预期的“HTTP/1.1 206 Partial Content”。

    URL requestURL = new URL(url);
    HttpURLConnection connection = (HttpURLConnection) requestURL.openConnection();
    try {
        connection.setRequestProperty("Connection", "close");
        connection.setReadTimeout(5000);

        assertEquals("Request successfully handled", 
                expectedResponseCode, 
                connection.getResponseCode());

        InputStream input = connection.getInputStream();
        try {
            return toString(input);
        } finally {
            input.close();
        }
    } finally {
        connection.disconnect();
    }

关于为什么会发生这种情况以及如何获得我想要的行为的任何想法?

4

3 回答 3

1

试试connection.getResponseMessage()方法?它可能包含找到实际代码的 REST 响应。连接响应可能已经到来,但在消息中可以找到实际的操作响应。

于 2012-05-25T17:49:20.190 回答
1

您发布的代码按预期执行。这是一个完整的测试用例来证明它:

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.URL;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;

public class Http206Test {
    private HttpServer server;

    @Before
    public void setUp() throws Exception {
        server = HttpServer.create(new InetSocketAddress(8080), 0);
        server.createContext("/", new HttpHandler() {
            public void handle(HttpExchange t) throws IOException {
                t.sendResponseHeaders(206, 0);
                t.getResponseBody().write("I'm a 206 response".getBytes());
                t.getResponseBody().close();
            }
        });
        server.start();
    }

    @After
    public void tearDown() throws Exception {
        server.stop(1);
    }

    @Test
    public void httpUrlConnection206Response() throws Exception {
        String body = getContent("http://localhost:8080", 206);
        assertThat(body, equalTo("I'm a 206 response"));
    }

    @Test(expected = AssertionError.class)
    public void httpUrlConnection205Response() throws Exception {
        getContent("http://localhost:8080", 205);
    }

    public String getContent(String url, int expectedResponseCode) throws IOException {
        URL requestURL = new URL(url);
        HttpURLConnection connection = (HttpURLConnection) requestURL.openConnection();
        try {
            connection.setRequestProperty("Connection", "close");
            connection.setReadTimeout(5000);
            assertEquals("Request successfully handled",
                    expectedResponseCode,
                    connection.getResponseCode());
            InputStream input = connection.getInputStream();
            try {
                return toString(input);
            } finally {
                input.close();
            }
        } finally {
            connection.disconnect();
        }
    }

    public String toString(InputStream stream) throws IOException {
        int data;
        StringBuilder builder = new StringBuilder();
        while ((data = stream.read()) != -1) {
            builder.append((char) data);
        }
        return builder.toString();
    }
}

这意味着您的测试是正确的,并且您的服务存在问题。

于 2012-05-25T18:08:54.437 回答
1

所以问题是我在设置响应代码之前调用了 write() 。虽然这在与 curl 一起使用时似乎有效,但它不适用于单元测试,因为代码在输入后立即断言返回代码。

问题代码:

String responseMessage = response.getMessage();
OutputStreamWriter out = new OutputStreamWriter(httpResponse.getOutputStream());
out.write(responseMessage);
out.close();
httpResponse.setContentType("application/json");
httpResponse.setContentLength(responseMessage.length());
httpResponse.setStatus(response.getResponseCode());

固定代码:

httpResponse.setStatus(response.getResponseCode()); //Do this first!
String responseMessage = response.getMessage();
OutputStreamWriter out = new OutputStreamWriter(httpResponse.getOutputStream());
out.write(responseMessage);
out.close();
httpResponse.setContentType("application/json");
httpResponse.setContentLength(responseMessage.length());
于 2012-05-25T18:30:43.093 回答