我想使用AdviceWith功能对产生到 RabbitMQ 的消息的 Camel 路由进行单元测试。
使用interceptSendToEndpoint
方法我可以将rabbitmq端点从原始路由重定向到模拟端点,但是 Camel 仍然尝试启动 RabbitMQ 生产者。
这是原始路线的简单版本:
@SpringBootApplication
public class SampleApplication {
static final String ROUTE_ID = "simple-route";
public static void main(String[] args) {
SpringApplication.run(SampleApplication.class, args);
}
@Bean
public RouteBuilder directToRabbitRoute() {
return new RouteBuilder() {
@Override
public void configure() {
from("timer://foo?period=5000").routeId(ROUTE_ID)
.log("message received, push to rabbit")
.to("rabbitmq:myexchange?autoDelete=false")
;
}
};
}
}
单元测试类(使用 camel-test-spring-junit5)
@SpringBootTest
@CamelSpringBootTest
@UseAdviceWith
public class SimpleRouteTest {
private static final String DIRECT_IN_URI = "direct:in";
@Autowired
private CamelContext camelContext;
@Test
void testSimple() throws Exception {
MockEndpoint mockedEndpoint = camelContext.getEndpoint("mock:foo", MockEndpoint.class);
mockedEndpoint.expectedMessageCount(1);
AdviceWith.adviceWith(camelContext, SampleApplication.ROUTE_ID, route -> {
route.replaceFromWith(DIRECT_IN_URI);
route.interceptSendToEndpoint("rabbitmq")
.skipSendToOriginalEndpoint()
.to(mockedEndpoint);
route.mockEndpointsAndSkip("rabbitmq:*"); // <<--- not working without this line
});
camelContext.start();
camelContext.createProducerTemplate().sendBody(DIRECT_IN_URI, "hello");
camelContext.stop();
}
}
这个单元测试工作正常(拦截工作正常,并且在模拟端点上收到了预期的消息),但我仍然可以在日志中看到 RabbitMQ 生成的日志已启动,我想避免这种情况。
我虽然这skipSendToOriginalEndpoint()
是用于此目的,但似乎并非如此。
2022-01-06 11:22:58.537 INFO 22140 --- [ Test worker] org.apache.camel.builder.AdviceWith : Adviced route before/after as XML:
<route xmlns="http://camel.apache.org/schema/spring" customId="true" id="simple-route">
<from uri="timer://foo?period=5000"/>
<log message="message received, push to rabbit"/>
<to uri="rabbitmq:myexchange?autoDelete=false"/>
</route>
<route xmlns="http://camel.apache.org/schema/spring" customId="true" id="simple-route">
<from uri="direct:in"/>
<interceptSendToEndpoint skipSendToOriginalEndpoint="true" uri="rabbitmq">
<to uri="mock://foo"/>
</interceptSendToEndpoint>
<log message="message received, push to rabbit"/>
<to uri="rabbitmq:myexchange?autoDelete=false"/>
</route>
2022-01-06 11:22:58.750 INFO 22140 --- [ Test worker] .c.m.InterceptSendToMockEndpointStrategy : Adviced endpoint [rabbitmq://myexchange?autoDelete=false] with mock endpoint [mock:rabbitmq:myexchange]
2022-01-06 11:22:58.834 WARN 22140 --- [ Test worker] o.a.c.c.rabbitmq.RabbitMQProducer : Failed to create connection. It will attempt to connect again when publishing a message.
java.net.BindException: Cannot assign requested address: connect
at java.base/sun.nio.ch.Net.connect0(Native Method) ~[na:na]
at java.base/sun.nio.ch.Net.connect(Net.java:579) ~[na:na]
at java.base/sun.nio.ch.Net.connect(Net.java:568) ~[na:na]
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:588) ~[na:na]
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
at com.rabbitmq.client.impl.SocketFrameHandlerFactory.create(SocketFrameHandlerFactory.java:60) ~[amqp-client-5.13.1.jar:5.13.1]
at com.rabbitmq.client.impl.recovery.RecoveryAwareAMQConnectionFactory.newConnection(RecoveryAwareAMQConnectionFactory.java:63) ~[amqp-client-5.13.1.jar:5.13.1]
at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.init(AutorecoveringConnection.java:160) ~[amqp-client-5.13.1.jar:5.13.1]
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1216) ~[amqp-client-5.13.1.jar:5.13.1]
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1173) ~[amqp-client-5.13.1.jar:5.13.1]
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1131) ~[amqp-client-5.13.1.jar:5.13.1]
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1325) ~[amqp-client-5.13.1.jar:5.13.1]
at org.apache.camel.component.rabbitmq.RabbitMQEndpoint.connect(RabbitMQEndpoint.java:247) ~[camel-rabbitmq-3.14.0.jar:3.14.0]
at org.apache.camel.component.rabbitmq.RabbitMQProducer.openConnectionAndChannelPool(RabbitMQProducer.java:108) ~[camel-rabbitmq-3.14.0.jar:3.14.0]
at org.apache.camel.component.rabbitmq.RabbitMQProducer.doStart(RabbitMQProducer.java:163) ~[camel-rabbitmq-3.14.0.jar:3.14.0]
at org.apache.camel.support.service.BaseService.start(BaseService.java:119) ~[camel-api-3.14.0.jar:3.14.0]
另外:如果我删除route.mockEndpointsAndSkip("rabbitmq:*");
单元测试失败的行(拦截/重定向到模拟端点不再完成,我不明白为什么......)
这个问题看起来像单元测试 Camel/RabbitMQ 路由问题,但接受的答案在我的情况下并不完全有效。