mardi 31 mai 2016

How to Unit Test a method using CountDownLatch?

I need to do the Unit Test of below code which is using countdownlatch. This is a test code only. I am using mockito thenAnswer and InvocationOnMask for mocking threads/callable. But I don't know how to initialize/mock or exit countdownlatch in unit testing.

public class ThreadPoolTaskExecRunner {
    private ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
    private ArrayBlockingQueue<String> values = new ArrayBlockingQueue<String>(100, true);

    public ThreadPoolTaskExecRunner() {
        threadPoolTaskExecutor.setCorePoolSize(5);
        threadPoolTaskExecutor.setMaxPoolSize(10);
        threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        threadPoolTaskExecutor.initialize();
    }

    public static void main(String args[]) {
        ThreadPoolTaskExecRunner obj = new ThreadPoolTaskExecRunner();
        obj.testCountDownLatch();
    }
    public void testCountDownLatch() {
        final CountDownLatch latch = new CountDownLatch(5);
        Future<String> future1 = threadPoolTaskExecutor.submit(new Task("A", values, latch));
        Future<String> future3 = threadPoolTaskExecutor.submit(new Task("B", values, latch));
        Future<String> future4 = threadPoolTaskExecutor.submit(new Task("C", values, latch));
        Future<String> future5 = threadPoolTaskExecutor.submit(new Task("D", values, latch));
        Future<String> future2 = threadPoolTaskExecutor.submit(new Task("E", values, latch));

        try{
            latch.await();  //main thread is waiting on CountDownLatch to finish
        }catch(InterruptedException ie){
            System.out.println(ie);
        }
        System.out.println("*********** DONE *********** values size= "+values.size());
        for(String s : values)
            System.out.println(s);
        threadPoolTaskExecutor.shutdown();
    }

    public static class Task implements Callable<String> {
        private String type;
        private ArrayBlockingQueue<String> values;
        private CountDownLatch latch;

        public Task(String s, ArrayBlockingQueue<String> values, CountDownLatch latch) {
            this.type = s;
            this.values = values;
            this.latch = latch;
        }

        @Override
        public String call() throws Exception {
            try {
                System.out.println("Inside call type: " + type);
                Thread.sleep(10);
                values.add(type);
                return type;
            } finally {
                if(latch != null)
                    latch.countDown();
            }
        }
    }
}

I developed the Unit Test class, But it is not helpful ...

@RunWith(MockitoJUnitRunner.class)
public class ThreadPoolTaskExecRunnerTest {
    @Mock
    private ThreadPoolTaskExecutor taskExecutor;

    @InjectMocks
    ThreadPoolTaskExecRunner threadPoolTaskExecRunner;

    @Test
    public void test() {
        when(taskExecutor.submit(any(ThreadPoolTaskExecRunner.Task.class))).thenAnswer(new Answer<Future<String>>() {
            public Future<String> answer(InvocationOnMock invocation) throws Throwable {
                Future<String> future = mock(FutureTask.class);
                when(future.isDone()).thenReturn(false, false, true);
                when(future.get()).thenReturn("This is a test");
                return future;
            }
        });

        threadPoolTaskExecRunner.testCountDownLatch();
    }
}

Aucun commentaire:

Enregistrer un commentaire