摘要:开发人员如何为http请求集成TEST超时?
背景故事:我的团队遇到了与异常持久的HTTP Web请求相关的问题。我们使用Apache的commons-httpclient
版本3。代码看起来类似于:
PostMethod post = new PostMethod(endpoint);
post.getParams().setSoTimeout(someInt);
httpClient.executeMethod(post);
完成此请求的时间通常是可以接受的(2秒左右),但偶尔,我们会看到50-60秒请求,尽管我们的SO超时设置为4秒。这促使我做了一些研究,发现大多数人都在设置连接超时ANNNNND SO超时。似乎应该将SO超时设置得更低(因为它们只是计算传输中字节之间的距离),并且连接超时是我们最初计划使用的(即请求和返回的第一个字节之间的初始延迟)。以下是我们编写并计划使用的代码:
httpClient.getHttpConnectionManager().getParams()
.setConnectionTimeout(someInt);
httpClient.getHttpConnectionManager().getParams()
.setSoTimeout(someInt);
这里的主要痛苦是我们无法集成测试这一变化。更确切地说,我们对如何集成测试从套接字连接到外部服务器的延迟感到困惑。在挖掘了commons-httpclient
之后,我看到了我们将不得不重现的受保护和私有类(因为它们是不可扩展的,并且不能从类外部使用),模拟并将这些类串起来最终到达java中的套接字类(依赖于它)在java native
方法 - 我们还需要通过模拟重现和注入 - 我不经常在那个级别看到的东西)。
我接触Stack Overflow的原因是看其他人如何测试这个/不测试它。我想避免不惜一切代价在性能环境中测试此功能。我的另一个想法是设置一个模拟服务器来响应具有可编程延迟时间的httpclient。我还没有看到这方面的例子。
首先,没有单元测试http请求 - 这将是集成测试。
其次,您可以使用JMeter之类的工具发送http请求,并测试是否在一定时间内收到响应as shown here in JMeter。
采用模拟服务器路由,我设法建立了一个带有API端点的小型Web服务器,我可以对其进行测试。这是相关的代码:
轻量级服务器设置:
TJWSEmbeddedJaxrsServer server = new TJWSEmbeddedJaxrsServer();
server.setPort(SERVER_PORT);
server.getDeployment().getResources().add(new TestResource());
server.start();
API端点:
/**
* In order to test the timeout, the resource will be injected into an embedded server.
* Each endpoint should have a unique use case.
*/
@Path("tests")
public class TestResource {
@POST
@Produces({MediaType.APPLICATION_XML})
@Path("socket-timeout")
public Response testSocketTimeout() throws InterruptedException {
Thread.sleep(SOCKET_TIMEOUT_SLEEP);
return Response.ok().build();
}
}
在api端点相关类中,我可以控制睡眠超时,然后在httpclient类中触发套接字超时。它有点hacky,但它可以按照我想要的方式测试功能(简单,轻量和有效)。