### Question:
BatchJobLogger { public <O, E, R extends BatchJobMutateResultInterface<O, E>> void logDownload( String downloadUrl, @Nullable BatchJobMutateResponseInterface<O, E, R> response, @Nullable Throwable throwable) { RequestInfo requestInfo = new RequestInfo.Builder() .withServiceName("batchjobdownload") .withContext(CONTEXT_NAME, null) .withUrl(downloadUrl) .build(); int resultsCount = 0; if (response != null && response.getMutateResults() != null) { resultsCount = response.getMutateResults().length; } ResponseInfo responseInfo = new ResponseInfo.Builder() .withPayload(String.format("Results count: %d", resultsCount)) .build(); RemoteCallReturn remoteCallReturn = new RemoteCallReturn.Builder() .withRequestInfo(requestInfo) .withResponseInfo(responseInfo) .withException(throwable) .build(); loggerDelegate.logRequestSummary(remoteCallReturn); loggerDelegate.logRequestDetails(remoteCallReturn); } @Inject  BatchJobLogger(@Named(AdWordsLoggingModule.BATCH_JOB_LOGGER_NAME) Logger batchJobLogger);   BatchJobLogger(RemoteCallLoggerDelegate loggerDelegate); void logUpload(
      String uploadContents,
      URI uploadUri,
      @Nullable BatchJobUploadResponse batchJobUploadResponse,
      @Nullable Throwable throwable); void logDownload(
      String downloadUrl,
      @Nullable BatchJobMutateResponseInterface<O, E, R> response,
      @Nullable Throwable throwable);  }### Answer:
@SuppressWarnings("unchecked") @Test public void testLogDownload() { BatchJobMutateResponseInterface< String, IllegalArgumentException, BatchJobMutateResultInterface<String, IllegalArgumentException>> response = Mockito.mock(BatchJobMutateResponseInterface.class); @SuppressWarnings("rawtypes") BatchJobMutateResultInterface[] mutateResults = new BatchJobMutateResultInterface[] { Mockito.mock(BatchJobMutateResultInterface.class), Mockito.mock(BatchJobMutateResultInterface.class) }; when(response.getMutateResults()).thenReturn(mutateResults); batchJobLogger.logDownload(url, response, exception); ArgumentCaptor<RemoteCallReturn> returnCaptor = ArgumentCaptor.forClass(RemoteCallReturn.class); verify(loggerDelegate).logRequestSummary(returnCaptor.capture()); RemoteCallReturn capturedReturn = returnCaptor.getValue(); assertEquals(exception, capturedReturn.getException()); RequestInfo requestInfo = capturedReturn.getRequestInfo(); assertEquals(url, requestInfo.getUrl()); assertEquals("clientCustomerId", requestInfo.getContextName()); assertNull(requestInfo.getContextValue()); assertNull(requestInfo.getPayload()); assertThat(requestInfo.getServiceName(), containsString("download")); ResponseInfo responseInfo = capturedReturn.getResponseInfo(); assertNull(responseInfo.getRequestId()); assertEquals("Results count: 2", responseInfo.getPayload()); verify(loggerDelegate).logRequestDetails(returnCaptor.capture()); assertSame( "The same RemoteCallReturn object was not passed to request details and request summary", capturedReturn, returnCaptor.getValue()); }
@Test public void testLogDownload_nullablesNull() { batchJobLogger.logDownload(url, null, null); ArgumentCaptor<RemoteCallReturn> returnCaptor = ArgumentCaptor.forClass(RemoteCallReturn.class); verify(loggerDelegate).logRequestSummary(returnCaptor.capture()); RemoteCallReturn capturedReturn = returnCaptor.getValue(); assertNull(capturedReturn.getException()); ResponseInfo responseInfo = capturedReturn.getResponseInfo(); assertEquals("Results count: 0", responseInfo.getPayload()); verify(loggerDelegate).logRequestDetails(returnCaptor.capture()); assertSame( "The same RemoteCallReturn object was not passed to request details and request summary", capturedReturn, returnCaptor.getValue()); }