0

我想使用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 路由问题,但接受的答案在我的情况下并不完全有效。

4

0 回答 0