2016-11-09 1 views
0

AsyncHttpClient를 사용하는 다음 코드에 대한 단위 테스트를 작성하고 있습니다. FutureCallback의 구현에서 CountDownLatch를 사용하고 CountDownLatch를 감소 시키면 카운트 다운 래치가 감소하기를 기다리는 동안 내 JUnit 테스트 케이스가 정지하게됩니다. JUnit 테스트 내에서 ArgumentCaptor를 사용하여 FutureCallback을 캡처 한 다음 thenAnswer를 사용하여 완성 된 메서드를 호출하여 카운트 다운 래치를 감소시킵니다. 그러나 효과가없는 것 같아서 어떤 아이디어라도 도움이 될 것입니다.Mockito thenAnswer가 예상대로 작동하지 않는 것 같습니다.

@Test 
public void testHttpError() throws InterruptedException, ExecutionException, TimeoutException { 
    StatusLine status = Mockito.mock(StatusLine.class); 
    when(status.getStatusCode()).thenReturn(400); 

    HttpResponse response = Mockito.mock(HttpResponse.class); 
    when(response.getStatusLine()).thenReturn(status); 

    Future<HttpResponse> future = Mockito.mock(Future.class); 
    when(future.get(anyLong(), any())).thenReturn(response); 

    CloseableHttpAsyncClient httpClient = Mockito.mock(CloseableHttpAsyncClient.class); 
    ArgumentCaptor<HttpUriRequest> requestCaptor = ArgumentCaptor.forClass(HttpUriRequest.class); 
    ArgumentCaptor<FutureCallback<HttpResponse>> futureCallbackCaptor = ArgumentCaptor.forClass((Class)FutureCallback.class); 
    when(httpClient.execute(any(), any())).thenReturn(future).thenAnswer(new Answer() { 

     @Override 
     public Object answer(InvocationOnMock invocation) throws Throwable { 
      verify(httpClient).execute(requestCaptor.capture(), futureCallbackCaptor.capture()); 
      futureCallbackCaptor.getValue().completed(response); 
      return null; 
     } 
    }); 

    StubbedRcaClient rcaClient = new StubbedRcaClient(httpClient); 
    Query query = new Query("abc", "xyz", RcaHttpRequestType.GET, 1000); 
    List<QueryResponse> res = rcaClient.execute(query); 
    assertEquals(0, res.size()); 
    IOUtils.closeQuietly(rcaClient); 
} 
+0

이 테스트에서 검증 로직을 포함하여 매우 복잡 다음과 같이

public List<QueryResponse> execute(Query query) { List<QueryResponse> res = new ArrayList<QueryResponse>(); try { List<HttpRequestBase> requests = query.generateHttpRequests(); List<Future<HttpResponse>> futures = new ArrayList<Future<HttpResponse>>(); final CountDownLatch requestCompletionCDLatch = new CountDownLatch(requests.size()); for (HttpRequestBase request : requests) { futures.add(httpClient.execute(request, new FutureCallback<HttpResponse>() { @Override public void failed(Exception e) { logger.error("Error while executing: " + request.toString(), e); requestCompletionCDLatch.countDown(); } @Override public void completed(HttpResponse result) { requestCompletionCDLatch.countDown(); } @Override public void cancelled() { logger.info("Request cancelled while executing: " + request.toString()); requestCompletionCDLatch.countDown(); } })); } requestCompletionCDLatch.await(); for (Future<HttpResponse> future : futures) { HttpResponse response = future.get(rcaRequestTimeout, TimeUnit.SECONDS); int status = response.getStatusLine().getStatusCode(); if (status != HttpStatus.SC_OK) { logger.warn("Query with non-success status " + status); } else { res.add(query.parseResponse(response.getEntity().getContent())); } } } catch (IOException | InterruptedException | ExecutionException | TimeoutException e) { logger.error("Error while querying", e); } catch (URISyntaxException e) { logger.error("Error while generating the query", e); } return res; } 

내 단위 테스트입니다 대답. 어쩌면 커뮤니티와 유지 보수 프로그래머가 쉽게 이해할 수 있도록 리팩토링 할 수 있습니까? 예를 들어, https://dzone.com/refcardz/mockito와 같은 좋은 단위 테스트의 예를 살펴보십시오. 주어진 명확한 구조/when/then이 있습니다. 유닛 테스트가 예상대로 작동한다는 관점에서'StubbedRcaClient'는 무엇이고'httpClient'에 올바르게 위임됩니까? 또한,'Future'를 조롱하지 마십시오 - 콜백이'get (long, TimeUnit)'또는'Future' 내 다른 메소드를 사용하는지 알지 못합니다. –

+0

HttpAsyncClient에서 응답을 조롱하려고합니다. t mock 미래 당신은 무엇을 제안합니까? – KunalC

+0

https://stackoverflow.com/questions/13866533/how-to-create-a-completed-future-in-java –

답변

0

나는 다음과 같이 내 JUnit을 업데이트하여이 작품을 만든 :

when(httpClient.execute(any(), any())).thenAnswer(new Answer<Future<HttpResponse>>() { 

    @Override 
    public Future<HttpResponse> answer(InvocationOnMock invocation) throws Throwable { 
     verify(httpClient).execute(requestCaptor.capture(), futureCallbackCaptor.capture()); 
     futureCallbackCaptor.getValue().completed(response); 
     return future; 
    } 
}); 
관련 문제