2017-04-12 45 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類到您的生產代碼!

而且這個模擬確實會返回一個「相同的線程執行器服務」;而不是「真正的服務」(基於線程池)。編寫這樣一個相同線程執行程序實際上很簡單 - 請參閱here

換句話說:你想2個不同的單元測試在這裏:

  1. 你寫在你的隔離類ExecutorServiceUtil單元測試;確保它做它應該做的事情(我認爲:檢查它是否返回一個非null的ExecutorService幾乎足夠好!)
  2. 您爲您的blah類編寫單元測試...使用模擬服務。突然之間,你所有的「異步」問題都會消失;因爲「異步」部分在空氣中消失。