0

I have this method:

public void updateService(JSONObject json, String url) throws IOException {
  PrintStream log = this.getLogger();
  CloseableHttpClient httpClient = null;

  httpClient = this.getCloseableHttpClient();
  log.println("Sending data to " + url);
  HttpPut request = new HttpPut(url);
  StringEntity params = new StringEntity(json.toString());
  request.addHeader("content-type", "application/json");
  request.setEntity(params);
  httpClient.execute(request);
  log.println("Sending report succeeded");
  httpClient.close();
}

My test then does this:

@Test
public void updateServiceCloseException() {
  RegistryTask task = new RegistryTask(false, null);
  RegistryTask spy = spy(task);
  CloseableHttpClient client = HttpClientBuilder.create().build();
  CloseableHttpClient clientSpy = spy(client);
  String url = "http://www.example.com/api/service/testo";
  String message = "Execute failure";

  JSONObject json = new JSONObject();
  json.put("name", "Bob");
  json.put("key", "testo");

  try {
    doReturn(clientSpy).when(spy).getCloseableHttpClient();

    // Make sure no http request is actually sent
    CloseableHttpResponse response = mock(CloseableHttpResponse.class);
    IOException exception = new IOException(message);

    doReturn(response).when(clientSpy).execute(any(HttpPut.class));
    doThrow(exception).when(clientSpy).close();

    spy.updateService(json, url);
  } catch (IOException e) {
    failWithTrace(e);
    // assertEquals(message, e.getMessage());
    return;
  } catch (Exception e) {
    failWithTrace(e);
    // assertEquals(message, e.getMessage());
    return;
  }

  fail("Exception not thrown");
}

For some reason doThrow(exception).when(clientSpy).close(); is saying Checked exception is invalid for this method!. But considering my method has throws IOException and close itself throws IOException, I am completely confused about getting this JUnit exception.

Update I tried updating the doReturn to when(clientSpy.execute(any(HttpPut.class))).thenReturn(response);. The new exception is java.lang.AssertionError: java.lang.IllegalArgumentException: HTTP request may not be null. Not sure why using any would count as null in this case. This question actually shows I should use doReturn since it always work vs thenReturn not working in all cases... Mockito - difference between doReturn() and when()

Dave Stein
  • 8,653
  • 13
  • 56
  • 104
  • Just to check: you are importing the right `IOException`? – Andy Turner Sep 19 '17 at 22:14
  • ha I'm away from desk right now but I do believe I copy pasted the import from actual class to test class. If it was wrong namespace I imagine I'd get compile error in real class. I'll double check when I get a minute though. – Dave Stein Sep 19 '17 at 22:25
  • Additionally, it's been a while since I used mockito, but it looks as though `doReturn` is only for void methods from the doc - and it looks from [here](https://stackoverflow.com/questions/12187274/mockito-exception-in-dothrow-that-looks-correct) like mockito can be finicky if you use a `doThrow` after what it thinks is unfinished stubbing. Can you try changing the previous line to `when(clientSpy.execute(...)).thenReturn(response)`? – Andy Turner Sep 19 '17 at 22:29
  • The when-first syntax is not for void methods. Mockito would throw an error. – Dave Stein Sep 19 '17 at 22:49
  • Right. But [`CloseableHttpClient.execute`](https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/client/CloseableHttpClient.html#execute(org.apache.http.client.methods.HttpUriRequest)) isn't void. – Andy Turner Sep 19 '17 at 23:58
  • Ah the joys of responding in subway station ;) I'll give your suggestion a shot by tomorrow. Thanks. – Dave Stein Sep 20 '17 at 00:25
  • @AndyTurner updated above with what happened, so no one misses comment and suggests same. – Dave Stein Sep 20 '17 at 14:49

1 Answers1

0

I changed from spy to full mock with CloseableHttpClient clientSpy = mock(CloseableHttpClient.class);. I know this removes all methods from running, but I was already using spy to override the two methods I was hitting. While this was the solution, I'd love a proper explanation as the answer for future readers.

Dave Stein
  • 8,653
  • 13
  • 56
  • 104