Reputation: 2181
I looked up some older questions here at SO and most of you say, don't test a void method.
I have a method which sends a HTTP Request to a Server and I think I still should test that even if the method is void? If not, please tell me why because many tutorials at dzone for example mention that you should test rest requests.
If I should test it, please help me to answer what I have to test and how I do that since void doesn't return anything. If you see another no go here please also tell me, I want to improve as much as I can.
Here is the Method:
private void buy(double price) {
final String timestamp = String.valueOf(System.currentTimeMillis());
final String amount = String.valueOf(observer.requestedAmount);
final String ressouce = GetValuesTypes.getRessource("user").get(observer.getRelatedUser);
String queryArgs = "wwww.doSomething.com/" + ressouce;
String hmac512 = HMAC512.hmac512Digest(queryArgs);
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost post = new HttpPost(GetValuesTypes.getURL());
post.addHeader("Key", GetValuesTypes.getKey());
post.addHeader("Sign", hmac512);
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("ressource", ressource));
params.add(new BasicNameValuePair("rate", String.valueOf(rate)));
params.add(new BasicNameValuePair("amount", amount));
params.add(new BasicNameValuePair("timestamp", timestamp));
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");
}
}
Upvotes: 0
Views: 1758
Reputation: 8858
You shouldn't test private
methods directly. Related threads:
However, if you're testing and you need to mock it, you can use PowerMock - Java framework that allows you to unit test code normally regarded as untestable. Code example: Mockito Mock Private Method Example with PowerMock
Upvotes: 1
Reputation: 131546
A void method doesn't return anything but you have ways to test it.
Here are the two mainly ways to do it :
A way that makes sense : checking the side effect that is generated by the implementation of the method. A method doesn't do nothing. So, you can check that it does what it should do.
A way that makes less sense : checking that dependencies of your method are invoked as these should be invoked. Finally you test nothing.
For example you just check/assert that the method a
is called with the object b
and that its result is used in the method c
as a parameter of it.
It is a test that records mocking behavior and tests that the record is called. It is not readable and you can record any behavior by mistake and not see the error in your test.
A unit test should favor the input (data that I want to test) and output (data that I expect to have) principle when it is possible.
That's why I favor the first way.
In your case the output generated by your void method seems be :
if (lastOrderNumber != -1) {
observer.setOrderNumber(lastOrderNumber);
}
In your unit test, you should have a way to get the observer
field.
In this way you can assert that it contains the order number with what you expect to.
Upvotes: 0