Search code examples
javamockingmockitopowermock

Is it possible to verify a mock method running in different thread in Mockito?


I have a method like the following,

public void generateCSVFile(final Date billingDate) {
    asyncTaskExecutor.execute(new Runnable() {
        public void run() {
            try {
                accessService.generateCSVFile(billingDate);
            } catch (Exception e) {
                LOG.error(e.getMessage());
            }
        }
    });
}

I have mocked:

PowerMockito.doNothing().when(accessService).generateCSVFile(billingDate);

But when I verify:

verify(rbmPublicViewAccessService, timeout(100).times(1)).generateCSVFile(billingDate);

It gives me as not invoked. Is this because it is invoked via separate thread, and is it possible to verify the methods called in different thread?


Solution

  • It is very likely that the Runnable hasn't been executed yet by the asyncTaskExecutor when you verify the invocation, resulting in a verification error in your unit test.

    The best way to fix this is to join on the generated thread and wait for execution before verifying the invocations.

    If you cannot get the instance of the thread, a possible work around is to mock the asyncTaskExecutor and implement it so it will execute the runnable directly.

    private ExecutorService executor;
    
    @Before
    public void setup() {
        executor = mock(ExecutorService.class);
        implementAsDirectExecutor(executor);
    }
    
    protected void implementAsDirectExecutor(ExecutorService executor) {
        doAnswer(new Answer<Object>() {
            public Object answer(InvocationOnMock invocation) throws Exception {
                ((Runnable) invocation.getArguments()[0]).run();
                return null;
            }
        }).when(executor).submit(any(Runnable.class));
    }