2014-03-27 5 views
2

누구든지 도움이 될지 궁금합니다. 10 초의 선발 기자는 JMS와 메시징에 대해 거의 알지 못한다는 점을 알고 있습니다. 따라서 어떤 대답/의견으로도 나와 함께 가시기 바랍니다 :)통합 테스트 방법 일부 Spring JMS 구성

저를위한 학습용 자료라고 생각하면 아주 기본적인 Spring JMS 설정을한데 모으고, 어떻게 작동하는지 이해할 수 있도록 몇 가지 통합 테스트를 작성하겠습니다.

이는 JMS 구성 요소와 내 현재 Spring 컨텍스트의 설정입니다 다음과 같이

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:p="http://www.springframework.org/schema/p" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:jms="http://www.springframework.org/schema/jms" 
     xmlns:amq="http://activemq.apache.org/schema/core" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans.xsd 
          http://www.springframework.org/schema/context 
          http://www.springframework.org/schema/context/spring-context.xsd 
          http://www.springframework.org/schema/jms 
          http://www.springframework.org/schema/jms/spring-jms.xsd 
          http://activemq.apache.org/schema/core 
          http://activemq.apache.org/schema/core/activemq-core.xsd"> 

    <bean class="com.lv.gi.jmstest.ApplicationContextProvider" /> 

    <!-- Embedded ActiveMQ Broker --> 
    <amq:broker id="broker" useJmx="false" persistent="false"> 
     <amq:transportConnectors> 
      <amq:transportConnector uri="tcp://localhost:0" /> 
     </amq:transportConnectors> 
    </amq:broker> 

    <!-- ActiveMQ Destination --> 
    <amq:queue id="destination" physicalName="myQueueName" /> 

    <!-- JMS ConnectionFactory to use, configuring the embedded broker using XML --> 
    <amq:connectionFactory id="jmsFactory" brokerURL="vm://localhost" /> 

    <!-- JMS Producer Configuration --> 
    <bean id="jmsProducerConnectionFactory" 
      class="org.springframework.jms.connection.SingleConnectionFactory" 
      depends-on="broker" 
      p:targetConnectionFactory-ref="jmsFactory" /> 

    <bean id="jmsProducerTemplate" class="org.springframework.jms.core.JmsTemplate" 
      p:connectionFactory-ref="jmsProducerConnectionFactory" 
      p:defaultDestination-ref="destination" /> 

    <bean class="com.lv.gi.jmstest.JmsMessageProducer"> 
     <constructor-arg index="0" ref="jmsProducerTemplate" /> 
    </bean> 

    <!-- JMS Consumer Configuration --> 
    <bean id="jmsConsumerConnectionFactory" 
      class="org.springframework.jms.connection.SingleConnectionFactory" 
      depends-on="broker" 
      p:targetConnectionFactory-ref="jmsFactory" /> 

    <jms:listener-container container-type="default" 
          connection-factory="jmsConsumerConnectionFactory" 
          acknowledge="auto"> 
     <jms:listener destination="myQueueName" ref="jmsMessageListener" /> 
    </jms:listener-container> 

    <bean id="jmsMessageListener" class="com.lv.gi.jmstest.JmsMessageListener" /> 
</beans> 

내 JmsMessageProducer 클래스는 PostMessage를 방법이 있습니다

public void postMessage(final String message) { 
    template.send(new MessageCreator() { 
     @Override 
     public Message createMessage(final Session session) throws JMSException { 
      final TextMessage textMessage = session.createTextMessage(message); 
      LOGGER.info("Sending message: " + message); 

      return textMessage; 
     } 
    }); 
} 

을 그리고 내 JmsMessageListener이 (MessageListener를 구현)는의 onMessage있다 방법은 다음과 같습니다 :

public void onMessage(final Message message) { 
    try { 
     if (message instanceof TextMessage) { 
      final TextMessage tm = (TextMessage)message; 
      final String msg = tm.getText(); 

      LOGGER.info("Received message '{}'", msg); 
     } 
    } catch (final JMSException e) { 
     LOGGER.error(e.getMessage(), e); 
    } 
} 

테스트 클래스에서 Spring 컨텍스트를 시작하고 JmsMessageProducer 빈을 가져 와서 postMessage를 호출 할 수있다. 나 시각적 메시지가 표시 이외의 콘솔에서 수신하기 때문에, 내가 메시지를 주장 할 수 없으며,이 작품 하다니

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath:/com/lv/gi/jmstest/JmsMessageListenerTest-context.xml" }) 
public class TestJms { 

    private JmsMessageProducer jmsMessageProducer; 

    @Before 
    public void setup() { 
     jmsMessageProducer = ApplicationContextProvider.getApplicationContext().getBean(JmsMessageProducer.class); 
    } 

    @Test 
    public void doStuff() throws InterruptedException { 
     jmsMessageProducer.postMessage("message 1"); 
    } 
} 

, 테스트의 그것 정말 많이하지 : 나는 예상대로 콘솔에 메시지가 표시 접수되었습니다.

우리는 mockito를 사용하기 때문에 MessageListener Bean을 모의로 대체 할 수있는 방법이 있는지 궁금하다. 나는이 테스트의 목적을 위해 다른 Spring 컨텍스트 파일을 제공함으로써이 작업을 수행 할 수 있다고 생각하지만, 다음 요구 사항에서는 제대로 작동하지 않을 수도있다.

내 목표는 주제를 만드는 것이며, 여기서 내 메시지 생성자는 큐에 메시지를 내보낼 수 있으며 더 많은 MessageListener 중 하나가 큐에서 메시지를 읽습니다. 등록 된 모든 리스너가 메시지를 읽으면 큐에서 메시지가 삭제됩니다. (주제가 이것에 대한 올바른 용어라고 생각합니다.)

이 시스템이 작동한다는 것을 증명하기 위해 Spring 컨텍스트를 실행할 수있는 테스트가 필요합니다. 내가하고 싶은 첫 번째 일은 청취자를 모두 같은 목적지에 배선 된 3 개의 가짜로 바꾸어서 각각에 대해 검증을 사용할 수있게하는 것입니다. 메시지를 게시 한 다음 각 모의 수령 사실을 확인합니다. 그런 다음 리스너 2 개를 제거/비활성화하고 postMessage를 호출하고 나머지 모의 리스너에서 onMessage 메서드가 호출되었는지 확인하려고합니다. 그런 다음 잠시 기다렸다가 2 개의 mock을 다시 설정하고 onMessage 메소드가 호출되었는지 확인하십시오. 마지막으로 메시지가 대기열에 없다는 것을 확인하십시오. (등록 된 3 명의 리스너가 모두 메시지를 수신했기 때문에)

위의 내용을 염두에두고 은 내가하려는 일을라고 생각합니다. 런타임에 대상에 대해 리스너를 등록 및 등록 취소 (또는 비활성화) 할 수 있습니다. 그렇게 할 수 있으면 mock을 등록 할 수 있습니다.

Phew !, 그것은 복잡합니다!하지만 나는 무엇을 하려는지에 대해 이해할 수 있기를 바랍니다.

어떻게해야합니까? 사전에 많은 감사,

나단 바로이 통합 테스트를하고있는 나의 의견으로는

+0

은,이 게시물은 청취자를 시작하고 중지하는 방법을 알려줍니다 : http://stackoverflow.com/questions/11407838/start-and-stop-jms-listener-using-spring 는 얼마나 운동해야 지금 청취자 등록 (내 모의 등록 가능) –

답변

0

는, 당신은 아무것도를 조롱하려고해서는 안된다.

한편으로는 단위 테스트를 작성합니다. 예를 들어 테스트에서 직접 jmsMessageListener의 onMessage 메소드를 호출하여 소비자의 행동을 테스트 할 수 있습니다. 일반적으로 이런 종류의 테스트에는 SpringJUnit4ClassRunner를 사용하지 않고 Mockito를 사용하여 테스트중인 객체의 종속성을 조롱합니다.

반면에 통합 테스트가 있습니다. 이것들은 전체 응용 프로그램의 동작을 테스트합니다. 여기서는 SpringJUnit4ClassRunner.class를 사용하는 것이 좋지만 Mockito는 사용하지 않는 것이 좋습니다. jmsListener가해야 할 것이 무엇이든 테스트가 완료되어야합니다. 예를 들어 응용 프로그램이 들어오는 메시지에 대한 로그를 작성한다고 가정하면 로그 파일을 열고 확인하십시오.

여기 예제는 매우 간단합니다. 어쩌면 이것이 내 생각에 혼란 스러울 수 있습니다. 보다 복잡한 리스너를 사용하면 시스템의 나머지 부분과 격리되는 것이 더 자연 스럽습니다.

OK
+0

귀하의 의견을 보내 주셔서 감사합니다. 어쩌면 내 용어가 단위 테스트 또는 통합 테스트와 관련하여 올바르지 않을 수 있습니다. 프로덕션 코드가 아니기 때문에 '테스트'하지 않을 것입니다. 이것은 JMS에 대한 나의 학습과 Spring 컨텍스트를 트리거하고 메시지를 트리거 할 수있게 해주는 테스트 클래스이며,받은 요청이 옳은 것 같았다. 나는 당신이 올바르게 통합 테스트에 적합하다고 말하는 SpringJUnit4ClassRunner를 사용하고 있기 때문에 통합 테스트라고 생각합니다. 나는이 모든 것들이 어떻게 작동 하는지를 알아 내려고 노력하고있다. –

+0

@NathanRussell, ok 나는 이해한다. 그런 다음 [spring-mockito] (https://bitbucket.org/kubek2k/springockito/wiki/Home)를 사용하여 모의 JmsMessageListener를 만들고 jmsListener 대신 사용할 수 있습니다. 그런 다음 테스트에 삽입하고 Mockito.verify를 사용하면됩니다. – Alban