In order to avoid having to change your actual @JmsListener method, you could try and use AOP in your test...
First create an aspect class like this:
@Aspect
public static class JmsListenerInterceptor {
@org.aspectj.lang.annotation.After("@annotation(org.springframework.jms.annotation.JmsListener)")
public void afterOnMessage(JoinPoint jp) {
// Do countdown latch stuff...
}
}
Then add it in your application context configuration you're using for testing, like this:
<aop:aspectj-autoproxy/>
<bean id="jmsListenerInterceptor" class="path.to.your.Test$JmsListenerInterceptor" />
If everything goes as planned, the JmsListenerInterceptor will count down and you don't have to change your actual code.
IMPORTANT: I just found out that using AOP and Mockito to verify if certain methods in your @JmsListener have been called is a bad combination. The reason seems to be the extra wrapping into CGLib classes resulting in the wrong/actual target instance to be invoked instead of the Mockito proxy.
In my test, I have an @Autowired, @InjectMocks Listener object and a @Mock Facade object for which I want to verify that a certain method has been called.
With AOP:
- Test Thread:
- [JmsListenerTest] 2279812 - class Listener$$EnhancerBySpringCGLIB$$6587f46b (wrapped by Spring AOP)
- [JmsListenerTest] 30960534 - class Facade$$EnhancerByMockitoWithCGLIB$$69fe8952 (wrapped by Mockito)
- Listener Thread:
- [Listener] 1151375 - class Listener (target instance of the AOP wrapped class)
- [Listener] 4007155 - class FacadeImpl (not the actual instance we expected)
Without AOP:
- Test Thread:
- [JmsListenerTest] 10692528 - class Listener (actual instance)
- [JmsListenerTest] 823767 - class Facade$$EnhancerByMockitoWithCGLIB$$773538e8 (wrapped by Mockito)
- Listener Thread:
- [Listener] 10692528 - class Listener (still actual instance)
- [Listener] 823767 - class Facade$$EnhancerByMockitoWithCGLIB$$773538e8
(still our mocked instance)
This goes to show that you'll need to watch out using AOP the way I tried to, as you might end up with different instances in both Threads...