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()
}
添加回答
舉報