Проверка лямбда-функции с резьбой в пружинном контроллере
У меня есть простая конечная точка в контроллере, как это:
private final ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(6);
@PostMapping(path = "/batch")
public ServiceResponse batch(@RequestBody BatchRequest request) {
threadPoolExecutor.submit(() -> {
try {
service.batch(request);
log.info("Batch finished");
} catch (Exception e) {
log.error("Failed to execute. Cause: ");
e.printStackTrace();
}
});
return ServiceResponse.asSuccess("Ok");
}
Это было сделано так, потому что запуск службы может занять несколько минут, поэтому мы избегаем блокировки всей системы. Я пытаюсь сделать модульный тест для этого и поймать его исключение (увеличение покрытия кода). Это то, что я придумал до сих пор
@Rule
public ExpectedException exception = ExpectedException.none();
@InjectMocks
private MyController controller;
@MockBean
private MyService service;
@Test
public void testBatchThrowsException() throws Exception {
createRequest();
when(service.batch(any())).thenThrow(Exception.class);
mockMvc.perform(post(Controller.URL_PREFIX+"/batch")
.contentType(MediaType.APPLICATION_JSON)
.content(request.toString()))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk());
exception.expect(Exception.class);
}
Но, конечно, он возвращает успех, так как поток все еще идет, когда запрос заканчивается. Есть ли способ высмеять исполнителя и получить результаты или что-то в этом роде? Я пытался использовать Awaitility, но не могу правильно вызвать лямбда-функцию.
1 ответ
Чтобы "вернуть что-то", единственное, что вы можете сделать, - это изменить реализацию кода контроллера (возможно, с использованием Future или чего-то еще).
Однако, если вы не можете сделать это, идея может заключаться в том, чтобы задержать основной поток в тестовом примере, а затем проверить, вызывается ли определенный метод.
Если вы не можете изменить реализацию реального кода, мой совет:
- ниже вызов контроллера в тестовом классе - задержать основной поток с Thread.sleep или что-то еще
- бросить макет исключения из службы
- проверять производственное поведение с помощью mockito: подсчитывать вызовы printStackTrace() при исключении mock, подсчитывать вызовы службы
- опционально - сделать тайм-аут на тесте, чтобы быть уверенным, что он длится ожидаемый период времени
Кроме того, прочитайте Ожидание всех потоков, порожденных моим тестируемым кодом в тестовом примере JUnit.