나는, 내가 액티브 MQ에 메시지를 펌프이 JmsTemplate을 사용하고 단위 테스트에의 JUnit에서의 JUnit 스프링 JMS 리스너
@Component
public class NotificationReader {
@JmsListener(destination = "myAppQ")
public void receiveMessage(NotificationMessage notificationMessage) {
System.out.println("Received <" + notificationMessage.getStaffNumber() + ">");
}
}
아래 간단한 JMS 리스너 코드를합니다.
jms 수신기가 호출되었는지 테스트하고 싶습니다.
How to wait for @JMSListener annotated method to complete in JUnit과 같은 몇 가지 솔루션 (카운터 사용)을 보았습니다.이 솔루션은 실제로 수행하려는 테스트 목적을 위해 리스너 코드를 실제로 변경합니다.
다른 대안이 있습니까?
답변에 제안 된대로 구성을 시도했습니다. 나는 testConfig을 추가하면
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestNotificationReader {
@Autowired
JmsTemplate jmsTemplate;
@Value("${outbound.endpoint}")
private String destination;
@Test
public void contextLoads() {
}
@Test
public void testPutToQ() {
NotificationMessage notificationMessage = new NotificationMessage();
notificationMessage.setStaffNumber("100");
notificationMessage.setWorkflowType("TYPE");
notificationMessage.setWorkflowId("100");
notificationMessage.setWorkflowDescription("Test From Queue");
jmsTemplate.convertAndSend(destination, notificationMessage);
jmsTemplate.setReceiveTimeout(10000);
try {
TestConfig.latch.await(10, TimeUnit.SECONDS);
NotificationMessage temp = (NotificationMessage) TestConfig.received;
System.out.println(" temp.getStaffNumber() " + temp.getStaffNumber());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Configuration
public static class TestConfig {
private static final CountDownLatch latch = new CountDownLatch(1);
private static Object received;
@Bean
public static BeanPostProcessor listenerWrapper() {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof NotificationReader) {
MethodInterceptor interceptor = new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Object result = invocation.proceed();
if (invocation.getMethod().getName().equals("receiveMessage")) {
received = invocation.getArguments()[0];
latch.countDown();
}
return result;
}
};
if (AopUtils.isAopProxy(bean)) {
((Advised) bean).addAdvice(interceptor);
return bean;
} else {
ProxyFactory proxyFactory = new ProxyFactory(bean);
proxyFactory.addAdvice(interceptor);
return proxyFactory.getProxy();
}
} else {
return bean;
}
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
return bean;
}
};
}
}
}
의 JMSTempate의를 autowiring은
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.jms.core.JmsTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
BeanPostProcessor()가 postProcessBeforeInitialization을 구현해야하므로이 코드를 컴파일 할 수 없습니다. 이 구성을 사용하면 기존 빈의 자동 연결 실패로 인해 컨텍스트로드가 실패합니다. 위에서 제공된 코드와 별도로 다른 코드가 필요한지 확인하십시오. – lives
예제는 Spring 5.0을 기반으로합니다. 내 편집을 참조하십시오. 당신은 더 이상 아무것도 필요하지 않습니다. BPP를'static'으로 선언하여 리스너 빈 앞에 등록되어 있는지 확인해야합니다. 그래도 작동하지 않으면 질문을 편집하여 COMPLETE 구성 및 테스트를 표시하십시오. –
당신의 대답을 감사하십시오. Gary Russel. 나는 아직도 그것을 작동하게 만들 수 없었다. 내 junit 테스트 코드를 게시했습니다 – lives