为了账号安全,请及时绑定邮箱和手机立即绑定

如何模拟 HttpClientBuilder 进行单元测试

如何模拟 HttpClientBuilder 进行单元测试

精慕HU 2023-08-04 15:49:22
我正在尝试为 http post 实现编写一个单元测试。但是,我无法正确模拟 httpclient,并且我的 when 语句永远不会被触发。我编写的单元测试是进行实际的 http 调用,而不是使用模拟响应进行响应。我们如何继续模拟 HttpClientBuilder 创建的客户端?Http方法实现:HttpResponse postRequest(String url, String request) {    HttpResponse resp = null;    try {        HttpClient client = HttpClientBuilder.create().useSystemProperties().build();        HttpPost post = new HttpPost(url);        post.addHeader("Content-Type", "application/x-www-form-urlencoded");        post.setEntity(new StringEntity(request));        resp = client.execute(post);    } catch (Exception e) {        return null;    }}测试方法:@Mockprivate HttpClient httpClient;when(httpClient.execute(any())).thenReturn(httpResponse);
查看完整描述

1 回答

?
饮歌长啸

TA贡献1951条经验 获得超3个赞

我们如何继续模拟 HttpClientBuilder 创建的客户端?


我们不!


尽量避免嘲笑第三方的担忧


创建紧密耦合的静态实现问题的抽象


public interface HttpClientFactory {

    public HttpClient create();

}

通过一个将在生产中使用的简单实现。


public class HttpClientFactoryImpl implements HttpClientFactory {


    //...


    public HttpClient create() {

        return HttpClientBuilder.create().useSystemProperties().build();

    }


    //...

}

使用依赖倒置,封装类应该显式依赖于抽象,以避免违反单一职责原则(SRP)


public class SystemUnderTest {


    private HttpClientFactory httpClientFactory;


    public SystemUnderTest(HttpClientFactory httpClientFactory) {

        this.httpClientFactory = httpClientFactory;

    }


    HttpResponse postRequest(String url, String request) {

        HttpResponse resp = null;

        try {

            HttpClient client = httpClientFactory.create();

            HttpPost post = new HttpPost(url);

            post.addHeader("Content-Type", "application/x-www-form-urlencoded");

            post.setEntity(new StringEntity(request));


            resp = client.execute(post);

            return resp;

        } catch (Exception e) {

            return null;

        }

    }

}

这种关注点分离 (SoC) 使其(您的封装类)能够更灵活地进行单独的单元测试。


@Test

public void testPostRequest() throws Exception {

    // Arrange

    HttpResponse expected = mock(HttpResponse.class);

    HttpClient httpClient = mock(HttpClient.class);

    when(httpClient.execute(any())).thenReturn(expected);


    HttpClientFactory httpClientFactory = mock(HttpClientFactory.class);

    when(httpClientFactory.create()).thenReturn(httpClient);


    SystemUnderTest systemUnderTest = new SystemUnderTest(httpClientFactory);


    String url = "http://url_here";

    String request = "Hello World";


    // Act

    HttpResponse actual = systemUnderTest.postRequest(url, request);


    // Assert

    assertEquals(expected, actual);

    //should also verify that the expected arguments as passed to execute()

}


查看完整回答
反对 回复 2023-08-04
  • 1 回答
  • 0 关注
  • 129 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信