I have a bean which executes a method doStuff
asynchronous, which of I am uncertain what is the best way to test the logic of that method doStuff
.
public class MyBean {
private final ExecutorService executorService;
@Inject
public MyBean(ExecutorService executorService) {
this.executorService = executorService;
}
public void work() {
doThings();
executorService.execute(() -> doStuff());
}
private void doThings(){
// ....
}
private void doStuff(){
// my code which needs to be run asynchronous
}
}
I could "open" the method doStuff()
to package protected, to be able to make a direct call in my Unit-Test. But changing productive code for testability is a strong bad smell.
In my unit test, I currently catch the argument which is given to the executorService mock, execute it and then do my asserts like a regular unit test. No change to the productive code is needed. But the tests seem much harder to read/understand:
@Mock
private ExecutorService executorService;
@InjectMocks
private MyBean myBean;
@Captor
ArgumentCaptor<Runnable> runnableCaptor;
@Test
void MyTest() {
myBean.work();
verify(executorService).execute(runnableCaptor.capture());
runnableCaptor.getValue().run();
// actually assert outcomings of running doStuff() Method
}
Is this acceptable? It doesn't seem very nice to me. How do I test this code as easy as possible? Are there maybe changes to be made to the productive code?