Search code examples
junitmockitorunnableprivate-methods

junit for multi threaded class with mockito


Please, help me write a JUnit test for this code using Mockito.

class A{
    private BlockingQueue<Runnable> jobQueue;

    public void methodA(List<String> messages) {
        try {
            jobQueue.put(() -> methodB(message));
        } catch(InterruptedException e) {}
    }

    private void methodB(Message message) {
        //other logic
    }
}

Solution

  • Your example lacks context as to what it is methodB is doing... Without knowing what the functionality is that you want to verify, just verifying that methodB gets called wouldn't be a particularly useful test, nor is mocking the BlockingQueue. I'm going to go out on a limb and assume that methodB interacts with another object, and it's this interaction that you really want to verify, if that's the case my code and test would look something like:

    class A {
        private BlockingQueue<Runnable> jobQueue;
        private B b;
    
        public void methodA(Message message) {
            try {
                jobQueue.put(() -> methodB(message));
            } catch (InterruptedException e) {
            }
        }
    
        private void methodB(Message message) {
            b.sendMethod(message);
        }
    }
    
    class B {
        public void sendMethod(Message message) {
            // other logic
        }
    }
    

    And my test would potentially look something like:

    class Atest {
    
        private A testSubject;
    
        @Mock
        private B b;
    
        @Test
        public void testASendsMessage() {
            Message message = new Message("HELLO WORLD");
            testSubject.methodA(message);
            verify(b, timeout(100)).sendMethod(message);
        }
    
        @Before
        public void setup() throws Exception {
            testSubject = new A();
        }
    }
    

    In general you want to avoid needing to verifying bits with multiple threads in a unit test, save tests with multiple running threads mainly for integration tests but where it is necessary look at Mockito.timeout(), see example above for how to use. Hopefully this helps?