使用LocalTestServer对HTTP调用进行单元测试

有时候,当您正在对远程服务器进行HTTP调用的单元测试代码时。 您可能正在使用诸如Apache'sHttpClient或Spring的RestTemplate之类的库。

当然,您不想依靠远程服务进行单元测试。 除了涉及的开销(记住单元测试应该是快速的)之外,您根本不能依赖于在执行测试期间可以使用的远程服务。 您可能还无法完全控制所有测试方案的响应。

考虑下面的简化示例。

ExampleHttpCall

public class ExampleHttpCall {

    private String serviceUrl;

    public ExampleHttpCall(String url) {
        serviceUrl = url;
    }

    public String doGet() {
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(serviceUrl, String.class);
        String response = responseEntity.getBody();
        return response;
    }

}

您将如何为ExampleHttpCall编写单元测试?

当然,您可以以这样的方式重新设计类,以使RestTemplate的实例被注入到类中:

ExampleHttpCall备用版本

@Component
public class ExampleHttpCallAlternateVersion {

    @Resource
    private RestTemplate restTemplate;

    private String serviceUrl;

    public ExampleHttpCallAlternateVersion(String url) {
        serviceUrl = url;
    }

    public String doGet() {
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(serviceUrl, String.class);
        String response = responseEntity.getBody();
        return response;
    }

}

现在可以嘲笑该依赖关系,从而使您可以更好地控制。 然而,由于附加的配置,该方法还导致增加的复杂性。 此外,您可能会遇到很多乏味的嘲笑。

对于这个简单的示例,使用模拟可能是解决方法。 但这并非总是如此。 如果是这样,另一种可能的方法是使用本地测试服务器。 碰巧的是,Apache HttpClient项目在其测试工件中提供了LocalTestServer。 如果您使用的是Maven,则可以通过添加以下依赖项将其包括在内:

<dependency>
	<groupId>org.apache.httpcomponents</groupId>
	<artifactId>httpclient</artifactId>
	<version>4.3.6</version>
	<classifier>tests</classifier>
	<scope>test</scope>
</dependency>

现在,您可以在单元测试中设置服务器:

LocalTestServer设置

private LocalTestServer server = new LocalTestServer(null, null);

@Before
public void setUp() throws Exception {
    server.start();
}

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

当然,仅启动和停止服务器并不能帮助您。 因此,您还需要另一种成分。 您将要注册一个或多个实现org.apache.http.protocol.HttpRequestHandler接口的处理程序,例如:

注册您的处理程序

server.register("/foo/*", myHttpRequestHandler);

HttpRequestHanlder接口将让您实现方法void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException;

该方法将使您完全控制HTTP响应。

因此,对于我们的原始示例,最小的单元测试可能类似于以下代码:

基本单元测试

public class ExampleHttpCallTest {


    private ExampleHttpCall exampleHttpCall;

    private LocalTestServer server = new LocalTestServer(null, null);

    private HttpRequestHandler myHttpRequestHandler = new HttpRequestHandler() {

        @Override
        public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException {
            response.setEntity(new StringEntity("foobar"));
        }

    };

    @Before
    public void setUp() throws Exception {
        server.start();
        server.register("/foo/*", myHttpRequestHandler);

        String serverUrl = "http:/" + server.getServiceAddress();
        exampleHttpCall = new ExampleHttpCall(serverUrl +"/foo/bar");
    }

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

    @Test
    public void test() {
        String result = exampleHttpCall.doGet();
        assertEquals("foobar", result);
    }

}

这就是开始所需要的全部。 从这里开始,您可以通过为每种可能的情况添加测试用例来进行详细说明。

翻译自: https://www.javacodegeeks.com/2015/08/unit-testing-http-calls-with-localtestserver.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值