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
相关产品推荐
相关产品推荐

