You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache Camel路由测试Mock端点失效,调用真实服务致断言失败

Apache Camel + Quarkus测试:Mock端点失效问题解决

问题场景

定义了如下Apache Camel路由,功能是拆分用户名集合,逐个调用邮件发送路由:

from(direct(Routes.SEND_EMAIL_BOP_SINGLE_PER_USER))
    .routeId(Routes.SEND_EMAIL_BOP_SINGLE_PER_USER)
    // Split the usernames on an individual exchange each. This property is a Set<String>.
    .split(simpleF("${exchangeProperty.%s}", ExchangeProperty.USERNAMES))
        // Set the flag for the next route's processor.
        .setProperty(ExchangeProperty.SINGLE_EMAIL_PER_USER, constant(true))
        .to(direct(Routes.SEND_EMAIL_BOP))
    .end();

编写对应的Quarkus测试时,尝试通过isMockEndpoints("*")Mock所有端点,但运行测试时Routes.SEND_EMAIL_BOP仍调用真实服务并报错,断言(预期5条消息,实际0条)失败。替换为isMockEndpointsAndSkip也无效:

@QuarkusTest
public class EmailRouteBuilderTest extends CamelQuarkusTestSupport {
    @Inject
    ProducerTemplate producerTemplate;

    @Override
    public String isMockEndpoints() {
        return "*";
    }

    @Test
    void testIndividualEmailPerUser() throws InterruptedException {
        final Set<String> usernames = Set.of("a", "b", "c", "d", "e");

        final Exchange exchange = this.createExchangeWithBody("");
        exchange.setProperty(ExchangeProperty.USERNAMES, usernames);

        final MockEndpoint sendEmailBopEndpoint = this.getMockEndpoint(String.format("mock:direct:%s", Routes.SEND_EMAIL_BOP), false);
        sendEmailBopEndpoint.expectedMessageCount(5);

        this.producerTemplate.send(String.format("direct:%s", Routes.SEND_EMAIL_BOP_SINGLE_PER_USER), exchange);

        sendEmailBopEndpoint.assertIsSatisfied();
    }
}

第一次AdviceWith尝试失败

改用AdviceWith修改测试,尝试MockRoutes.SEND_EMAIL_BOP路由的所有端点,但出现NullPointerException,断言仍失败:

@QuarkusTest
public class EmailRouteBuilderTest extends CamelQuarkusTestSupport {
    @Inject
    ProducerTemplate producerTemplate;

    @Override
    public boolean isUseAdviceWith() {
        return true;
    }

    @Test
    void testIndividualEmailPerUser() throws Exception {
        AdviceWith.adviceWith(this.context, Routes.SEND_EMAIL_BOP, a -> {
            a.mockEndpointsAndSkip("*");
        });

        final Set<String> usernames = Set.of("a", "b", "c", "d", "e");

        final Exchange exchange = this.createExchangeWithBody("");
        exchange.setProperty(ExchangeProperty.USERNAMES, usernames);

        final MockEndpoint sendEmailBopEndpoint = this.getMockEndpoint(String.format("mock:direct:%s", Routes.SEND_EMAIL_BOP), false);
        sendEmailBopEndpoint.expectedMessageCount(5);

        this.producerTemplate.send(String.format("direct:%s", Routes.SEND_EMAIL_BOP_SINGLE_PER_USER), exchange);

        sendEmailBopEndpoint.assertIsSatisfied();
    }
}

最终解决方案

调整AdviceWith的目标路由,改为在被测路由(Routes.SEND_EMAIL_BOP_SINGLE_PER_USER)中指定要Mock的direct:Routes.SEND_EMAIL_BOP端点,测试最终通过:

@QuarkusTest
public class EmailRouteBuilderTest extends CamelQuarkusTestSupport {
    @Inject
    ProducerTemplate producerTemplate;

    @Override
    public boolean isUseAdviceWith() {
        return true;
    }

    @Test
    void testIndividualEmailPerUser() throws Exception {
        AdviceWith.adviceWith(this.context, Routes.SEND_EMAIL_BOP_SINGLE_PER_USER, a -> {
            a.mockEndpointsAndSkip(String.format("direct:%s", Routes.SEND_EMAIL_BOP));
        });

        final Set<String> usernames = Set.of("a", "b", "c", "d", "e");

        final Exchange exchange = this.createExchangeWithBody("");
        exchange.setProperty(ExchangeProperty.USERNAMES, usernames);

        final MockEndpoint sendEmailBopEndpoint = this.getMockEndpoint(String.format("mock:direct:%s", Routes.SEND_EMAIL_BOP), false);
        sendEmailBopEndpoint.expectedMessageCount(5);

        this.producerTemplate.send(String.format("direct:%s", Routes.SEND_EMAIL_BOP_SINGLE_PER_USER), exchange);

        sendEmailBopEndpoint.assertIsSatisfied();
    }
}

原因说明

当路由通过to(direct:XXX)调用另一个路由时,要Mock这个调用,需要在发起调用的路由上使用AdviceWith修改to端点,而不是直接修改目标路由。这样才能让被测路由的流量转向Mock端点,同时跳过真实调用。

内容的提问来源于stack exchange,提问作者MikelAlejoBR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 07:55:40