我正在尝试学习用 Java 编写可测试的代码。我看到很多链接说如果我想做单元测试,单例类不太好实现。这就是我想要解决的问题。我有一个发送 HTTP 请求的类(HTTPRequest 类)。我希望这个类担心使用哪个协议(protocol)(TLSv1.2 等)。我有多个其他类,它们仅使用正文、URL 等调用 HTTPRequest 类。
我的方法是 HTTPRequest 可以是一个单例类,因为不需要创建同一事物的多个实例。整个项目的协议(protocol)将是相同的,并且只需要设置一次。
这就是我的 HTTPRequest 的样子。
public class HTTPRequest {
private CloseableHttpClient httpClient;
private HttpGet httpGet;
private HttpPut httpPut;
private HttpPost httpPost;
HTTPRequest(CloseableHttpClient a, HttpGet b, HttpPut c, HttpPost d) {
httpClient = a;
httpGet = b;
httpPut = c;
httpPost = d;
}
public HTTPResponse getRequest(url) {
//Do some processing with httpClient & httpGet to send the request
}
}
现在,从需要 HTTPRequest 的类中,有一种方法可以调用 getRequest,但只使用一个对象吗?我读过一些有关依赖注入(inject)的内容,但我真的不知道应该如何做。
我应该如何修改代码以使其也可测试?
最佳答案
你可以做的就是删除 HTTPRequest
中的构造函数类,然后创建 protected
名为 getHttpGet()
的方法, getHttpPut
等
public class HTTPRequest {
public HTTPResponse getRequest(url) {
//Do some processing with httpClient & httpGet to send the request
getHttpGet(url).call();
}
protected CloseableHttpClient getHttpClient() {
return new CloseableHttpClient();
}
protected HttpGet getHttpGet(String url) {
return new HttpGet(url);
}
protected HttpPost getHttpPost(String url) {
return new HttpPost(url);
}
...
}
然后,您可以创建一个 HttpRequestMock
继承自 HttpRequest
的类并覆盖getHttp*
方法。
public class HTTPRequestMock extends HttpRequest {
@Override
protected CloseableHttpClient getHttpClient() {
//return mock
return new CloseableHttpClientMock();
}
@Override
protected HttpGet getHttpGet(String url) {
//return mock
return new HttpGetMock(url);
}
@Override
protected HttpPost getHttpPost(String url) {
//return mock
return new HttpPostMock(url);
}
...
}
最后,可以注入(inject)HttpRequest
或HttpRequestMock
相应地在您的单元测试中。
class HTTPRequestClient {
private HTTPRequest httpRequest = HttpRequestFactory.getHttpRequest();
public void callServer(){
httpRequest.getRequest("http://someurl.com/");
}
void setHttpRequest(HTTPRequest httpRequest){
this.httpRequest = httpRequest;
}
}
class HTTPRequestFactory {
private static final HttpRequest httpRequest = new HttpRequest();
public static HTTPRequest getHttpRequest() {
return httpRequest;
}
}
class HTTPRequestClientTest {
HTTPRequestClient httpRequestClient;
@Before
public void setUp(){
httpRequestClient = new HTTPRequestClient();
httpRequestClient.setHttpRequest(new HttpRequestMock());
}
@Test
...
}
关于java - 如何使用单例类实现依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41625811/