我想知道是否有人可以提供幫助。我的第一個10的原因是我對JMS和消息一般知之甚少(幾乎沒有) - 所以請隨時與我聯繫,並提供任何答案/評論:)如何集成測試一些Spring JMS配置
鑑於這對我來說是一種學習方式,我試圖組合一個非常基本的Spring JMS配置,然後編寫一些集成測試來幫助我理解它是如何工作的。
這是我目前的Spring上下文配置與它的JMS組件:
<?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 bean並調用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上下文文件來實現,但這可能不適合我的下一個要求...
我的最終目標是創建一個主題,我的消息生產者可以將消息發送到隊列中,其中1個MessageListeners將從隊列中讀取消息,並且當所有註冊的偵聽器都讀取消息時,消息將從隊列中刪除。 (我認爲話題是這個正確的術語!)
爲了證明這個系統可以工作,我想要一個測試,在那裏我可以啓動Spring上下文。我想要做的第一件事是用3個連接到相同目的地的mock替換掉監聽器,這樣我就可以在每個連接上使用驗證。我會發布消息,然後確認每個模擬都已收到。然後,我想要刪除/禁用兩個監聽器,調用postMessage,並驗證onMessage方法是在剩下的一個模擬監聽器上調用的。然後或許等一會兒,然後重新建立2個mock,並驗證他們的onMessage方法被調用。最後,檢查消息不再在隊列中(由於3個已註冊的聽衆已全部收到消息)
考慮到上述情況,我想認爲我正在嘗試做什麼在運行時註冊並取消註冊(或禁用)針對目標的偵聽器,如果我可以這樣做,那麼我可以註冊mock。
Phew !,這很複雜!但我希望它對我想要做什麼有意義?
任何指針如何實現這一目標?事先非常感謝,
彌敦道
OK,這篇文章告訴我如何啓動和停止監聽器: http://stackoverflow.com/questions/11407838/start-and-stop-jms-listener-using-spring 只需要找出如何現在註冊聽衆(所以我可以註冊我的嘲笑) –