Я использую Spring ThreadPoolTaskExecutor
для выполнения задач в нескольких потоках.Класс выглядит следующим образом:
@Component
public class LoadData {
//... ...
@Inject
private ThreadPoolTaskExecutor taskExecutor;
public SomeData getData(Long id) {
Future<SomeData> loadData = taskExecutor.submit(() -> {
//return methodToGetDataSynchronously(id);
return new SomeData();
});
try {
SomeData data = loadData.get();
} catch (InterruptedException | ExecutionException e) {
logger.error("error");
//some more processing for the error here
}
return data;
}
}
Чтобы иметь возможность провести модульное тестирование этого класса и охватить ветви InterruptedException
и ExecutionException
, я пробовал несколько подходов (используя Mockito
Spy
), ноне удалось успешно проверить это.
Класс модульного теста выглядит следующим образом:
@RunWith(MockitoJUnitRunner.class)
public class LoadDataTest {
@InjectMocks
private LoadData loadData;
@Spy
private ThreadPoolTaskExecutor spyTaskExecutor = new ThreadPoolTaskExecutor();
@Before
public void init() {
MockitoAnnotations.initMocks(this);
spyTaskExecutor.setCorePoolSize(1);
spyTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
spyTaskExecutor.initialize();
}
@Test
public void testGetData_shouldThrowInterruptedException () {
Mockito.when(spyTaskExecutor.submit(Matchers.<Callable<SomeData>>any())).thenAnswer(new Answer<Future<SomeData>>() {
public Future<SomeData> answer(InvocationOnMock invocation) throws Throwable {
Future<SomeData> future = Mockito.mock(FutureTask.class);
when(future.isDone()).thenReturn(false, false, true);
when(future.get()).thenThrow(new InterruptedException ());
return future;
}
});
SomeData result = null;
result = loadData.getData(101L);
//verify here that InterruptedException processing was performed
}
}
Я использую Spy
для ThreadPoolTaskExecutor
, так как у меня есть другие методы в тесте, которыепроверяет фактическое поведение многопоточного исполнения.Когда я пытаюсь запустить тестовый метод, он бросает NullPointerException
в шпионский шпион:
Mockito.when(spyTaskExecutor.submit(Matchers.<Callable<SomeData>>any()))...
Исключение:
java.lang.NullPointerException
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:132)
at org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor.submit(ThreadPoolTaskExecutor.java:320)
at com.company.LoadDataTest.testGetData_shouldThrowInterruptedException(LoadDataTest.java:20)
Я думаю, проблема может быть в том, как яя заглушаю шпиона Мокито.Однако я не уверен, что нахожусь на правильном пути, чтобы заглушить InterruptedException
.Кто-нибудь получил пример того, как этого добиться?
Версии:
jdk-1.8.0_72
junit-4.12
mockito-core-1.10.19
spring-context-4.3.4.RELEASE
Примечание: это выдержка из реального кода.Фактический код выполняет много других вещей, и в него вводятся многие другие bean-компоненты - некоторые из них Mock
в Test
, некоторые Spy
- в зависимости от того, что я тестирую.Я упомянул только ту часть, с которой я столкнулся здесь.