我有一个发布事件E1的A类。 E1在由@RabbitListener
注释的同一应用程序中由B类使用。 B做了一些事情然后发布了由C等消耗的事件E2(形成一个流程链)。
我想做的是两件事:
RabbitListener's
,以便不执行作为E1发布结果的整个过程。我只想断言A做了它应该发布的并发布了E1。我设法通过设置spring.rabbitmq.listener.auto-startup=false
。RabbitListerner
。但我再也不希望C被称为E2的副作用。我知道我可以使用模拟做到这一点但最好是我想测试真实的交易并使用实际的组件(包括将消息发送到实际的RabbitMQ实例,在我的情况下是在Docker中运行)。
我可以在Spring Boot中以一种很好的方式实现这一目标吗?或者是否建议使用@RabbitListenerTest
并确实使用模拟?
答案 0 :(得分:5)
@RabbitListener
有id
属性:
/**
* The unique identifier of the container managing for this endpoint.
* <p>If none is specified an auto-generated one is provided.
* @return the {@code id} for the container managing for this endpoint.
* @see org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistry#getListenerContainer(String)
*/
String id() default "";
RabbitListenerEndpointRegistry#getListenerContainer(String)
返回MessageListenerContainer
,您已经可以控制start()/stop()
个人@RabbitListener
处理程序。{/ p>
答案 1 :(得分:0)
accepted answer的后续想法是拥有某种抽象的BaseAmqpIntegrationTest
,它可以完成以下任务:
public abstract class BaseAmqpIntegrationTest {
@Autowired
protected RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry;
@BeforeEach
protected void setUpBeforeEach() {
rabbitListenerEndpointRegistry.getListenerContainers()
.forEach(Lifecycle::stop);
getRequiredListenersToStart().forEach(listener -> rabbitListenerEndpointRegistry.getListenerContainer(listener)
.start());
}
protected abstract List<String> getRequiredListenersToStart();
}
这使得它可以重用,并确保所有“ @RabbitListener
”都被“默认”禁用,并且要求每个测试显式启用它测试的侦听器。然后,测试子类可以简单地重写getRequiredListenersToStart()
来提供它们所需的@RabbitListener
的ID。
PS:清理它当然也可以:
public abstract class BaseAmqpIntegrationTest {
@AfterEach
protected void cleanUpAfterEach() {
rabbitListenerEndpointRegistry.getListenerContainers()
.forEach(Lifecycle::stop);
}
}
或更细粒度:
public abstract class BaseAmqpIntegrationTest {
@AfterEach
protected void cleanUpAfterEach() {
getRequiredListenersToStart().forEach(listener -> rabbitListenerEndpointRegistry.getListenerContainer(listener)
.stop());
}
}