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()
}
添加回答
举报