我有一些使用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();
}
关于为什么会发生这种情况以及如何获得我想要的行为的任何想法?
答案 0 :(得分:1)
尝试connection.getResponseMessage()
方法?它可能包含找到实际代码的REST响应。连接响应可能已经到来,但可以在消息中找到实际的操作响应。
答案 1 :(得分: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();
}
}
这意味着您的测试是正确的,并且您的服务存在问题。
答案 2 :(得分: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());