Spring JMS 集成单元测试将消息留在队列中
Spring JMS Integration Unit Test leaves message on queue
我正在使用 Spring 4.3.5.Release 和 ActiveMQ 5.14.3 来处理消息队列。
这是我在应用程序上下文文件中的定义:
<!-- Activemq connection factory -->
<bean id="amqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<!-- brokerURL, You may have different IP or port -->
<constructor-arg index="0" value="${message.broker.url}" />
</bean>
<!-- Pooled Spring connection factory -->
<bean id="jmsConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<constructor-arg ref="amqConnectionFactory" />
</bean>
<!-- ======================================================= -->
<!-- JMS Send, define default destination and JmsTemplate -->
<!-- ======================================================= -->
<!-- Default Destination Queue Definition -->
<bean id="defaultDestination" class="org.apache.activemq.command.ActiveMQQueue">
<!-- name of the queue -->
<constructor-arg index="0" value="${default.message.queue}" />
</bean>
<bean id="jmsDestinationResolver" class="org.springframework.jms.support.destination.DynamicDestinationResolver"/>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="jmsConnectionFactory"/>
<property name="defaultDestination" ref="defaultDestination" />
<property name="destinationResolver" ref="jmsDestinationResolver"/>
<property name="pubSubDomain" value="${pub.sub.domain}"/>
<property name="receiveTimeout" value="${receive.timeout}"/>
</bean>
下面是在默认队列上创建消息的代码:
public boolean sendResponse(final MyObjectDTO myObject) {
boolean success = false;
this.jmsTemplate.convertAndSend(ebvResponse);
success = true;
return success;
}
这是我的单元测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations =
{ "classpath:/spring/my-platform-services-context.xml" })
@Transactional
public class MessageUtilTest extends TestCase {
@Autowired
private MessageUtil messageUtil;
@Test
public void testConvertSendMessageToDefault() throws JsonParseException, JsonMappingException, IOException {
MyObjectDTO myObject = new ManualCoverageDTO();
myObject.setMessage(message);
boolean success = messageUtil.sendResponse(myObject);
assertEquals(true, success);
}
}
此测试效果很好,消息正确进入队列!
我希望测试结束时,因为单元测试是事务性的,消息会从队列中回滚,但似乎并没有。
我知道这是一个 "integrated" 测试,因为它实际上是在接触 ActiveMQ 服务器并将消息放入队列。
那么,我怎样才能使它真正具有事务性,以便我刚放入队列的消息在完成后真正回滚,我是否必须手动告诉此测试回滚?
我已经对数据库进行了数百次 "integrated" 单元测试,在一次测试中每次插入、更新或删除之后,以及测试结束时,数据库都会回滚到声明它是在测试之前,我希望我的消息队列或主题发生同样的事情。
任何帮助都将非常有用。谢谢!
您需要将 JmsTemplate
上的 sessionTransacted
设置为 true
。
但是,请记住,除非您提交,否则您将无法在任何地方收到测试消息。
我正在使用 Spring 4.3.5.Release 和 ActiveMQ 5.14.3 来处理消息队列。
这是我在应用程序上下文文件中的定义:
<!-- Activemq connection factory -->
<bean id="amqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<!-- brokerURL, You may have different IP or port -->
<constructor-arg index="0" value="${message.broker.url}" />
</bean>
<!-- Pooled Spring connection factory -->
<bean id="jmsConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<constructor-arg ref="amqConnectionFactory" />
</bean>
<!-- ======================================================= -->
<!-- JMS Send, define default destination and JmsTemplate -->
<!-- ======================================================= -->
<!-- Default Destination Queue Definition -->
<bean id="defaultDestination" class="org.apache.activemq.command.ActiveMQQueue">
<!-- name of the queue -->
<constructor-arg index="0" value="${default.message.queue}" />
</bean>
<bean id="jmsDestinationResolver" class="org.springframework.jms.support.destination.DynamicDestinationResolver"/>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="jmsConnectionFactory"/>
<property name="defaultDestination" ref="defaultDestination" />
<property name="destinationResolver" ref="jmsDestinationResolver"/>
<property name="pubSubDomain" value="${pub.sub.domain}"/>
<property name="receiveTimeout" value="${receive.timeout}"/>
</bean>
下面是在默认队列上创建消息的代码:
public boolean sendResponse(final MyObjectDTO myObject) {
boolean success = false;
this.jmsTemplate.convertAndSend(ebvResponse);
success = true;
return success;
}
这是我的单元测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations =
{ "classpath:/spring/my-platform-services-context.xml" })
@Transactional
public class MessageUtilTest extends TestCase {
@Autowired
private MessageUtil messageUtil;
@Test
public void testConvertSendMessageToDefault() throws JsonParseException, JsonMappingException, IOException {
MyObjectDTO myObject = new ManualCoverageDTO();
myObject.setMessage(message);
boolean success = messageUtil.sendResponse(myObject);
assertEquals(true, success);
}
}
此测试效果很好,消息正确进入队列!
我希望测试结束时,因为单元测试是事务性的,消息会从队列中回滚,但似乎并没有。
我知道这是一个 "integrated" 测试,因为它实际上是在接触 ActiveMQ 服务器并将消息放入队列。
那么,我怎样才能使它真正具有事务性,以便我刚放入队列的消息在完成后真正回滚,我是否必须手动告诉此测试回滚?
我已经对数据库进行了数百次 "integrated" 单元测试,在一次测试中每次插入、更新或删除之后,以及测试结束时,数据库都会回滚到声明它是在测试之前,我希望我的消息队列或主题发生同样的事情。
任何帮助都将非常有用。谢谢!
您需要将 JmsTemplate
上的 sessionTransacted
设置为 true
。
但是,请记住,除非您提交,否则您将无法在任何地方收到测试消息。