java-在竞争的使用者队列上侦听的多个测试应用程序上下文会导致间歇性测试失败
作者:互联网
我有一个正在测试的JMSInboundGateway,它侦听Apache Artemis队列(竞争使用者).我的测试将消息发送到Artemis服务器,并模拟目标服务.如果调用了模拟服务,那么我已经验证了JmsInboundGateway的设置正确.
流程如下所示:
测试发件人-> Artemis Queue-> JmsInboundGateway-> DirectChannel-> ServiceActivator->模拟(目的地服务)
如果测试是JUnit测试套件中唯一运行的测试类,则它会像冠军一样运行.但是,如果套件中还有其他测试类,则测试将失败.我已经跟踪到,当测试失败时,Artemis队列最多有三个使用方:我假设两个用于不具有Mocked服务bean的ApplicationContext,另一个用于具有模拟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(“ messaging”)的测试中,那么当存在多个消息传递测试时,这确实可以解决问题.在测试套件执行期间,我仅观察到Artemis队列上的一个使用者,并且我可以启用多个消息传递的测试类.
// The following appears to permit me to have multiple messaging enabled tests
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("messaging")
@DirtiesContext
public class MessagingTest { ... }
在我看来,这也很笨拙,但这是迄今为止我最好的解决方案.是否有我缺少的测试帮助程序和/或模式可以帮助我解决此问题?
非常感谢!
解决方法:
有了@DirtiesContext,您真的走对了.
您在测试类的应用程序上下文之间共享JMS资源的问题.这就是您真正与一个或另一个现有使用者发生冲突的方式,只是因为在执行期间缓存了另一个类的整个应用程序上下文,并且它可以访问JMS以及您的当前上下文.
实际上,这就是几年前我们在Spring Integration中为JMS和JDBC测试解决类似问题的方式.我们还要求Spring Test Framework开发人员将其作为默认功能来执行,但这听起来是一个重大突破,对于不共享资源的典型单元测试来说,这是不合理的.
从那里开始,我们有一个方向要始终考虑我们的测试是否启动了某些后台线程或是否可以访问共享资源,例如嵌入式MongoDB,Hazelcast或文件系统上的某个目录.因此,在这些情况下,我们一定使用@DirtiesContext并对通过的测试感到非常满意.
标签:spring-boot,spring-test,integration-testing,java,spring-integration 来源: https://codeday.me/bug/20191108/2010140.html