2017-04-12 90 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类编写单元测试...使用模拟服务。突然之间,你所有的“异步”问题都会消失;因为“异步”部分在空气中消失。