我正在测试一个JMSInboundGateway,它监听Apache Artemis队列(竞争消费者)。我的测试向Artemis服务器发送一条消息,并模拟目标服务。如果调用了模拟服务,那么我已经验证了JmsInboundGateway的设置是否正确。
流程如下所示:Test Sender -> Artemis Queue -> JmsInboundGateway -> DirectChannel -> ServiceActivator -> Mock(Destination Service)
如果测试类是JUnit测试套件中唯一运行的测试类,那么它就像冠军一样运行;但是,如果套件中有其他测试类,则测试失败。我发现,当测试失败时,Artemis队列最多有三个消费者:我假设两个是针对没有模拟服务bean的ApplicationContexts的,另一个是针对具有模拟bean的上下文的。测试通过还是失败取决于正确的上下文是否接收到消息。
我尝试过的一件事似乎是工作是可选地注册JmsInboundGateway时,一个特定的配置文件是活跃的,只激活该配置文件的消息传递测试(和现场应用程序当然)。
// Declaring my inbound gateways with the profile requirement
@Profile("messaging")
@Bean
public JmsInboundGateway jmsInboundGateway(ConnectionFactory connFactory) { ... }
// Running my tests with
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("messaging")
public class MessagingTest { ... }
这将导致消息窃取上下文永远不会侦听队列上的消息,并允许适当的上下文作为独占侦听器。这不是一个特别令人满意的解决方案,因为我可能有多个测试类需要“消息传递”配置文件,并且我已经验证了它们会相互影响。
如果我将@DirtiesContext注解添加到每个标记有@ActiveProfiles(“消息传递”)的测试中,那么当存在多个消息传递测试时,这似乎确实解决了问题。在测试套件执行期间,我只观察Artemis队列上的一个消费者,我可以有多个启用消息传递的测试类。
// The following appears to permit me to have multiple messaging enabled tests
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("messaging")
@DirtiesContext
public class MessagingTest { ... }
这对我来说似乎也很笨拙,但这是我迄今为止最好的解决方案。有没有我所缺少的测试助手和/或模式可以帮助我解决这个问题?
多谢了!
1条答案
按热度按时间hyrbngr71#
有了
@DirtiesContext
,你真的走对了路。在测试类中的应用程序上下文之间共享JMS资源的问题。这就是您如何真正与一个或另一个现有消费者发生冲突的原因,因为另一个类的整个应用程序上下文在执行期间被缓存,并且它可以访问JMS以及您的当前上下文。
这确实是我们几年前在Spring Integration中解决JMS和JDBC测试中类似问题的方法。我们还要求Spring Test Framework开发人员将此作为默认功能,但这听起来是一个很大的突破性变化,对于不共享资源的典型单元测试来说是不合理的。
因为我们一直在思考我们的测试是否启动了一些后台线程或访问了一个共享资源,例如。嵌入式MongoDB,Hazelcast或只是文件系统上的某个目录。所以,在这些情况下,我们肯定会使用
@DirtiesContext
,并且对通过的测试非常满意。