Mockito capture value on spy object in when method

Viewed 148

I want to do something depending on the value is being passed to spy object ExecutorService. I want to just .doCallRealMethod() or throw exception and test whether my logic is correct. I cannot figure out how to do this with mockito. I have example code of my logic:

public class TasksRunner {

    @Autowired
    private ExecutorService executorService;

    public void runTasks(List<Task> tasks) {

        for(Task task : task) {
            Worker = new Worker(task);
            try {
                executorService.submit(worker);
            } catch(RejectedExecutionException e) {
                // logic
            }
        }

        // logic
    }
}

And test code:

var executorService = spy(Executors.newFixedThreadPool(THREAD_POOL_SIZE));

when(executorService.submit(argThat(new ArgumentMatcher<Worker>() {
    @Override
    public boolean matches(Worker w) {
        // logic 
        return w.isSomething();
    }
}))).thenThrow(new RejectedExecutionException());

// logic

It is not complete code, but problem is, that this expression in "when" is like being called - and I see on the debugger that there is a call to AbstractExecutorService::submit(Callable) and I get NullPointerException from submit method, because there is a check whether passed argument is null.

Maybe this is not the appropriate approach with mockito. My question is how to write such a test at all that checks which worker is passed to ExecutorService and either call real method or throw exception.

1 Answers

Okay, I figured this out.

It has to be:

doThrow(new RejectedExecutionException()).when(executorService).submit(Matchers.<Worker>argThat(w -> w.isSomething()));

Notice that .submit() is not directly in when() clause. When it is, it really calls ExecutorService and its super AbstractExecutorService where NullPointerExceptions is thrown.

Related