java - 如何使用mockito stub 异步调用?

标签 java asynchronous mockito executorservice powermockito

假设我有两个类一起工作来执行这样的可调用:

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 stub 响应并立即返回?

我尝试了以下方法,但我的 innovcation.args() 返回 [null]

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;
                    }
                });

最佳答案

您可以通过在测试代码中使用ExecutorServiceUtil来实现这一点。我的意思是:您向生产代码提供该 util 类的模拟!

该模拟确实返回“同一线程执行器服务”;而不是“真正的服务”(基于线程池)。编写这样的同线程执行器实际上很简单 - 请参阅 here .

换句话说:您需要在这里两个不同的单元测试:

  1. 您单独为 ExecutorServiceUtil 类编写单元测试;确保它做了它应该做的事情(我认为:检查它是否返回一个非空的 ExecutorService 几乎就足够了!)
  2. 您为您的 blah 类编写单元测试...使用模拟服务。突然之间,所有围绕“它是异步”的问题都消失了;因为“异步”部分消失得无影无踪。

关于java - 如何使用mockito stub 异步调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43381227/

相关文章:

java - SimpleDateFormat 导致时间不正确

java - 查找特定的异常和相应的消息

c# - Realm 数据库异步查询和.Net

javascript - 如何在客户端 nodejs 处理异步请求?

javascript - 许多 facebook 喜欢页面上的按钮,异步

java - 模拟 Socket.getOutputStream() 用于测试 Java

java - 如何在 java 中使用 mockito 测试文件大小?

java - Java 类内部的方法调用返回 "identifier expected after this token"错误

java - 映射结构 : mocking nested mapper

java - 如何在没有 ImageIO.read() 的情况下将加载的字节转换为图像