Java CompletableFuture.allOf().get()不在单元测试中运行

Java CompletableFuture.allOf().get()不在单元测试中运行,java,junit,Java,Junit,我有一个异步构建多个DTO的方法。它在一般情况下运行良好,所以我正在尝试为它编写一些单元测试。该方法如下所示: public List clientleadboard(@RequestBody List accountIds)引发ExecutionException、InterruptedException{ List-clients=newarraylist(accountIds.size()); 长启动=System.currentTimeMillis(); 列表期货=新的ArrayList

我有一个异步构建多个DTO的方法。它在一般情况下运行良好,所以我正在尝试为它编写一些单元测试。该方法如下所示:

public List clientleadboard(@RequestBody List accountIds)引发ExecutionException、InterruptedException{
List-clients=newarraylist(accountIds.size());
长启动=System.currentTimeMillis();
列表期货=新的ArrayList();
for(字符串accountId:accountId){
期货.add(
CompletableFuture.runAsync(()->{
buildSurgeClientDto(SurgeClient,accountId);
},遗嘱执行人)
);
}
CompletableFuture.allOf(futures.toArray(新的CompletableFuture[futures.size())).get();
log.info(“所用时间:{}ms”,System.currentTimeMillis()-start);
回报客户;
}
我的测试结果如下:

@测试
@肮脏的环境
public void TestGetLeadboard()引发异常{
//给定
最终清单账户=新的ArrayList();
最终字符串accountOne=“ABCDE”;
最后一个字符串accountTwo=“ZYXWV”;
最后一个字符串accountThree=“FAKE!”;
最后一个字符串clientForename=“John”;
最后一个字符串clientname=“Smith”;
ClientDetailsCursorResult validOne=ClientDetailsCursorResult.builder()
.accountId(accountOne)
.forename(clientForename)
.姓氏(客户姓氏)
.build();
ClientDetailsCursorResult validTwo=ClientDetailsCursorResult.builder()
.accountId(accountTwo)
.forename(clientForename)
.姓氏(客户姓氏)
.build();
BalanceDetailsTo ValidBalanceDetailsTo=新的BalanceDetailsTo();
ValidBalanceDetailsTo.SetAvailableToDraw(100d);
ValidBalanceDetailsTo.setAvailableBalance(100d);
账户。添加(账户一);
账户。添加(账户二);
账户。添加(账户三);
//什么时候
当(accountMaintenanceRestClient.getAccount(accountOne))。然后返回(accountDTO());
当(accountMaintenanceRestClient.getAccount(accountTwo))。然后返回(accountDTO());
当(accountMaintenanceRestClient.getAccount(accountThree))。然后返回(null);
when(clientDetailsJdbc.getClientAccounts(accountOne)).thenReturn(Arrays.asList(validOne));
when(clientDetailsJdbc.getClientAccounts(accountTwo)).thenReturn(Arrays.asList(validTwo));
当(balanceDetailsService.getBalanceDetails(accountOne)),然后返回(ValidBalanceDetailsTo);
当(balanceDetailsService.getBalanceDetails(accountTwo))。然后返回(ValidBalanceDetailsTo);
列出surgeClientDtos=surgeParisController.clientLeaderboard(客户);
//然后
断言(surgeClientDtos.get(0.getAccountId(),是(accountOne));
断言(surgeClientDtos.get(0.getAvailableToTrade(),为(100d));
断言(surgeClientDtos.get(0.GetAvailableToDraw(),为(100d));
断言(surgeClientDtos.get(0.getClientName())为(clientForename+“”+ClientNames));
}
当我运行测试时,它会陷入一个没有输出的无限循环中。调试代码时,要执行的最后一行是

CompletableFuture.allOf(futures.toArray(newcompletablefuture[futures.size()).get()

我在
buildSurgeClientDto()
中放置了一个断点,并再次尝试在调试模式下运行,但从未触发该断点


为什么会这样?测试async
CompletableFutures
,我需要做一些特殊的事情吗?

问题是您需要模拟
Executor
。它只是从不执行任务,所以测试只是挂起。您只需使用simple executor并将其注入控制器即可:

private Executor executor = Executors.newSingleThreadExecutor();
而不是

@Mock
private Executor executor;
对于你的测试来说,它应该是有效的。您不需要测试
Executor
CompletableFuture
,因为它是JDK的一部分,并且经过了良好的测试

但是,如果您需要mock executor,您应该mock或stub:

// CompletableFuture code:
executor.execute(new AsyncRun(dep, function)); 

否则测试将挂起。

问题在于您模拟了执行器。它只是从不执行任务,所以测试只是挂起。您只需使用simple executor并将其注入控制器即可:

private Executor executor = Executors.newSingleThreadExecutor();
而不是

@Mock
private Executor executor;
对于你的测试来说,它应该是有效的。您不需要测试
Executor
CompletableFuture
,因为它是JDK的一部分,并且经过了良好的测试

但是,如果您需要mock executor,您应该mock或stub:

// CompletableFuture code:
executor.execute(new AsyncRun(dep, function)); 

否则测试将挂起。

测试使用了什么
executor
?啊。。。一个我似乎嘲笑过的人…什么
executor
用于测试?啊。。。一个我似乎嘲笑过的人。。。