【问题标题】:Disable JMS consuming bean in unit-test在单元测试中禁用 JMS 消费 bean
【发布时间】:2017-10-24 08:01:10
【问题描述】:
我已经构建了一个接收 JMS 消息 (@JmsListener) 的 Spring 应用程序。
在开发过程中,我想向侦听器侦听的 JMS 队列发送一些消息,因此我编写了一个发送一些消息的单元测试 (JmsTemplate)。在这个单元测试中,我使用@SpringBootTest 和@RunWith(SpringRunner.class) 来加载应用程序上下文(数据源的bean 等)。
但是,当单元测试开始时,它还会加载 jms 侦听器 bean,它直接开始使用我的新消息。
我想在这个测试场景中禁用这个 jms 侦听器 bean,以便将消息添加到队列中。然后,我可以启动主应用程序并观察它们的使用情况。
我应该如何处理这个问题?
我想我也可以问一下我一般如何禁用 bean。
提前致谢。
【问题讨论】:
标签:
java
spring
unit-testing
jms
javabeans
【解决方案1】:
您可以使用配置文件来解决这个问题。
为你的监听器添加@Profile注解:
@Profile("!test-without-jmslistener")
public class JmsListenerBean {
...
}
这告诉 Spring 如果配置文件“test-without-jmslistener”不处于活动状态(感叹号否定条件),它应该只创建此 bean 的实例。
在您的单元测试类中,添加以下注释:
@ActiveProfiles("test-without-jmslistener)
public class MyTest {
...
}
现在 Spring 测试运行器将在运行您的测试之前激活此配置文件,并且 Spring 不会加载您的 bean。
【解决方案2】:
除了使用配置文件,您还可以使用属性来实现:
@ConditionalOnProperty(name = "jms.enabled", matchIfMissing = true)
public class JmsListenerBean {
...
}
matchIfMissing 属性告诉 Spring 默认将此属性设置为 true。
在您的测试类中,您现在可以禁用 JmsListenerBean:
@TestPropertySource(properties = "jms.enabled=false")
public class MyTest {
...
}
【解决方案3】:
此问题的另一种解决方案:在测试类中添加@ComponentScan() 以跳过指定bean 的加载。
@SpringBootTest
@RunWith(SpringRunner.class)
@ComponentScan(basePackages="com.pechen.demo", excludeFilters=@Filter(type=FilterType.ASSIGNABLE_TYPE, classes=JmsListener.class))
public class MyTest(){
}
更多请参考spring component scan include and exclude filters。
【解决方案4】:
我认为您可以通过以下代码做到这一点:-
private void stopJMSListener() {
if (customRegistry == null) {
customRegistry = context.getBean(JmsListenerEndpointRegistry.class);
}
customRegistry.stop();
}
private void startJMSListener() {
if (customRegistry == null) {
customRegistry = context.getBean(JmsListenerEndpointRegistry.class);
}
customRegistry.start();
}