我尝试测试一个使用CloseableHttpClient连接的方法。我决定去Mockito并嘲笑所有相关的类和方法。但是,一旦我开始测试,它就会直接进入真实服务器,而不是被模拟的CloseableHttpClient拦截。
测试
@Test
public void testBid() throws IOException {
//given:
HttpGet httpGet = mock(HttpGet.class);
HttpResponse httpResponse = mock(HttpResponse.class);
StatusLine statusLine = mock(StatusLine.class);
ObserverImp observer = mock(ObserverImp.class);
CloseableHttpClient closeableHttpClient = mock(CloseableHttpClient.class);
CloseableHttpResponse closeableHttpResponse = mock(CloseableHttpResponse.class);
//and:
when(statusLine.getStatusCode()).thenReturn(200);
when(httpResponse.getStatusLine()).thenReturn(statusLine);
when(closeableHttpClient.execute(httpGet)).thenReturn(closeableHttpResponse);
when(observer.getKey()).thenReturn("##213");
Buy buy = new Buy(observer);
buy.bid(14455);
}
相关的实施
public void buy(double price) {
String queryArgs = "command=order&amount=1" + "&price=" + String.valueOf(price); // generates query
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost post = new HttpPost("wwww.hm.edu/projectGroup1");
post.addHeader("Key", observer.getKey());
try {
post.setEntity(new ByteArrayEntity(queryArgs.getBytes("UTF-8")));
} catch (UnsupportedEncodingException e) {
System.out.println("Exception in run");
}
List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("command", "order"));
params.add(new BasicNameValuePair("amount", "1"));
params.add(new BasicNameValuePair("price", String.valueOf(price)));
try {
post.setEntity(new UrlEncodedFormEntity(params));
CloseableHttpResponse response = httpClient.execute(post);
HttpEntity entity = response.getEntity();
Scanner in = new Scanner(entity.getContent());
String orderNumber = "";
while (in.hasNext()) {
orderNumber = in.nextLine();
}
String[] findOrderNumber = orderNumber.split(".");
long lastOrderNumber = -1;
try {
lastOrderNumber = Long.valueOf(findOrderNumber[3]);
} catch (NumberFormatException exception) {
System.out.println("NumberFormatException");
} finally {
if (lastOrderNumber != -1) {
observer.setOrderNumber(lastOrderNumber);
}
}
in.close();
EntityUtils.consume(entity);
httpClient.close();
} catch (IOException e) {
System.out.println("Exception occured during process");
}
}
我尝试了几个在教程或类似问题中找到的测试代码片段,但没有成功。你能告诉我我在这里做错了什么吗?
谢谢:)
答案 0 :(得分:0)
在buy
方法中,您使用静态方法创建httpClient
,如下所示
CloseableHttpClient httpClient = HttpClients.createDefault();
现在,每当您致电buy
时,真正的 http客户端都会被创建并调用真实服务。相反,您应该从测试代码中传递httpClient
作为模拟httpClient
的依赖项,例如
public void buy(double price, HttpClient httpClient) {
..
}
并且在测试中:
public void test() {
HttpClient httpClient = mock(HttpClient.class)
// mock the behavour
// SUT
buy(..., httpClient);
}
答案 1 :(得分:0)
您可以通过构造函数注入CloseableHttpClient httpClient
:
public class Buy {
private ObserverImp observer;
private CloseableHttpClient httpClient;
public Buy (ObserverImp observer, CloseableHttpClient httpClient) {
this.observer = observer;
this.httpClient = httpClient;
}
public void buy(double price) {
...
// Comment or remove the line below and use the injected instead...
// CloseableHttpClient httpClient = HttpClients.createDefault();
...
}
}
要测试它,请遵循:
@Test
public void testBid() throws IOException {
//given:
HttpGet httpGet = mock(HttpGet.class);
HttpResponse httpResponse = mock(HttpResponse.class);
StatusLine statusLine = mock(StatusLine.class);
ObserverImp observer = mock(ObserverImp.class);
CloseableHttpClient closeableHttpClient = mock(CloseableHttpClient.class);
CloseableHttpResponse closeableHttpResponse = mock(CloseableHttpResponse.class);
//and:
when(statusLine.getStatusCode()).thenReturn(200);
when(httpResponse.getStatusLine()).thenReturn(statusLine);
when(closeableHttpClient.execute(httpGet)).thenReturn(closeableHttpResponse);
when(observer.getKey()).thenReturn("##213");
Buy buy = new Buy(observer, closeableHttpClient);
buy.bid(14455);
}