У меня есть метод, который асинхронно создает несколько DTO.Он хорошо работает в общем случае, поэтому я пытаюсь написать для него несколько юнит-тестов.Метод выглядит следующим образом:
public List<SurgeClientDto> clientLeaderboard(@RequestBody List<String> accountIds) throws ExecutionException, InterruptedException {
List<SurgeClientDto> surgeClients = new ArrayList<>(accountIds.size());
long start = System.currentTimeMillis();
List<CompletableFuture> futures = new ArrayList<>();
for (String accountId : accountIds) {
futures.add(
CompletableFuture.runAsync(() -> {
buildSurgeClientDto(surgeClients, accountId);
}, executor)
);
}
CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])).get();
log.info("Time taken: {}ms", System.currentTimeMillis() - start);
return surgeClients;
}
, а мой тест выглядит следующим образом:
@Test
@DirtiesContext
public void testGetLeaderboard() throws Exception {
// Given
final List<String> accounts = new ArrayList<>();
final String accountOne = "ABCDE";
final String accountTwo = "ZYXWV";
final String accountThree = "FAKE!";
final String clientForename = "John";
final String clientSurname = "Smith";
ClientDetailsCursorResult validOne = ClientDetailsCursorResult.builder()
.accountId(accountOne)
.forename(clientForename)
.surname(clientSurname)
.build();
ClientDetailsCursorResult validTwo = ClientDetailsCursorResult.builder()
.accountId(accountTwo)
.forename(clientForename)
.surname(clientSurname)
.build();
BalanceDetailsDto validBalanceDetailsDto = new BalanceDetailsDto();
validBalanceDetailsDto.setAvailableToWithdraw(100d);
validBalanceDetailsDto.setAvailableBalance(100d);
accounts.add(accountOne);
accounts.add(accountTwo);
accounts.add(accountThree);
// When
when(accountMaintenanceRestClient.getAccount(accountOne)).thenReturn(accountDTO());
when(accountMaintenanceRestClient.getAccount(accountTwo)).thenReturn(accountDTO());
when(accountMaintenanceRestClient.getAccount(accountThree)).thenReturn(null);
when(clientDetailsJdbc.getClientAccounts(accountOne)).thenReturn(Arrays.asList(validOne));
when(clientDetailsJdbc.getClientAccounts(accountTwo)).thenReturn(Arrays.asList(validTwo));
when(balanceDetailsService.getBalanceDetails(accountOne)).thenReturn(validBalanceDetailsDto);
when(balanceDetailsService.getBalanceDetails(accountTwo)).thenReturn(validBalanceDetailsDto);
List<SurgeClientDto> surgeClientDtos = surgeParisController.clientLeaderboard(accounts);
// Then
assertThat(surgeClientDtos.get(0).getAccountId(), is(accountOne));
assertThat(surgeClientDtos.get(0).getAvailableToTrade(), is(100d));
assertThat(surgeClientDtos.get(0).getAvailableToWithdraw(), is(100d));
assertThat(surgeClientDtos.get(0).getClientName(), is(clientForename + " " + clientSurname));
}
Когда я запускаю свой тест, он застревает в бесконечном цикле без вывода.Когда я отлаживаю код, последняя строка для выполнения будет
CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])).get();
Я поместил точку останова в buildSurgeClientDto()
и попытался снова запустить в режиме отладки, но точка останова никогда не срабатывает.
Почему это?Что-то особенное, что я должен сделать, чтобы проверить асинхронность CompletableFutures
?