2017-04-12 6 views
0

내가이 같은 호출을 실행하기 위해 함께 작동하는 두 개의 클래스가 있다고 가정 :mockito로 비동기 호출을 스텁하는 방법은 무엇입니까?

public class blah { 

@Autowired 
private ExecutorServiceUtil executorServiceUtil; 

@Autowired 
private RestTemplate restClient; 

public SomeReturnType getDepositTransactions(HttpHeaders httpHeaders) { 

    ExecutorService executor = executorServiceUtil.createExecuter(); 
    try { 
     DepositTransactionsAsyncResponse asyncResponse = getPersonalCollectionAsyncResponse(httpHeaders, executor); 
     // do some processing 
     // return appropriate return type 
    }finally { 
     executorServiceUtil.shutDownExecutor(executor); 
    } 
} 

Future<ResponseEntity<PersonalCollectionResponse>> getPersonalCollectionAsyncResponse(HttpHeaders httpHeaders, ExecutorService executor) { 

    PersonalCollectionRequest personalCollectionRequest = getpersonalCollectionRequest(); // getPersonalCollectionRequest populates the request appropriately 
    return executor.submit(() -> restClient.exchange(personalCollectionRequest, httpHeaders, PersonalCollectionResponse.class)); 
    } 
} 

public class ExecutorServiceUtil { 

    private static Logger log = LoggerFactory.getLogger(ExecutorServiceUtil.class); 

    public ExecutorService createExecuter() { 
     return Executors.newCachedThreadPool(); 
    } 

    public void shutDownExecutor(ExecutorService executor) { 
      try { 
       executor.shutdown(); 
       executor.awaitTermination(5, TimeUnit.SECONDS); 
      } 
      catch (InterruptedException e) { 
       log.error("Tasks were interrupted"); 
      } 
      finally { 
       if (!executor.isTerminated()) { 
        log.error("Cancel non-finished tasks"); 
       } 
       executor.shutdownNow(); 
      } 
     } 

} 

가 어떻게이 응답을 스텁하고 즉시 반환 Mockito를 사용할 수 있습니까?

나는 다음 시도했지만 한 내 innovcation.args() 반환 [널]

PowerMockito.when(executor.submit(Matchers.<Callable<ResponseEntity<OrxPendingPostedTrxCollectionResponseV3>>> any())).thenAnswer(new Answer<FutureTask<ResponseEntity<OrxPendingPostedTrxCollectionResponseV3>>>() { 

      @Override 
      public FutureTask<ResponseEntity<OrxPendingPostedTrxCollectionResponseV3>> answer(InvocationOnMock invocation) throws Throwable { 
       Object [] args = invocation.getArguments(); 
       Callable<ResponseEntity<OrxPendingPostedTrxCollectionResponseV3>> callable = (Callable<ResponseEntity<OrxPendingPostedTrxCollectionResponseV3>>) args[0]; 
       callable.call(); 
         return null; 
        } 
       }); 
+0

@ GhostCat의 제안을 통해 나는 호출을 동 기적으로 반환 할 수 있었고, 대답 논리를 제거 할 수있었습니다. – Norbert

답변

1

당신은 으로 사용하지 그렇게 당신의 테스트 코드에서 ExecutorServiceUtil. 무슨 뜻입니까? 모의을 util 코드로 제작 코드에 제공하십시오!

그리고 그 모의는 "같은 스레드 실행자 서비스"를 반환합니다; 대신 "실제 서비스"(스레드 풀 기반). 같은 thread-executor를 쓰는 것은 실제로는 직선적이다. here을 참조하라. 즉

: 여기 이 개 다른 단위 테스트하려면 :

  1. 당신은 격리에 ExecutorServiceUtil 클래스에 대한 단위 테스트를 쓰기; 그것이해야 할 일을하는지 확인하십시오. (생각하면 : null이 아닌 ExecutorService를 리턴하는 것이 거의 충분합니다!)
  2. 조롱 된 서비스를 사용하는 blah 클래스에 대한 단위 테스트를 작성합니다 . 갑자기 모든 문제가 "비동기식"으로 사라집니다. 왜냐하면 "비동기"부분은 얇은 공기에서 사라지기 때문입니다.