Apache Camel测试:mockEndpointsAndSkip()未收消息,weaveById替换可行
Apache Camel单元测试:mockEndpointsAndSkip("*")失效问题
问题场景
我搭建了如下基础Camel路由:
public class TestRoute extends RouteBuilder { @Override public void configure() throws Exception { from("jpa:Data").to("jpa:Data").id("testId"); } }
在单元测试中尝试使用mockEndpointsAndSkip("*")批量模拟所有端点,测试代码如下,但执行时报错:mock://jpa:Data Received message count. Expected: <1> but was: <0>
public class RouteTest extends CamelTestSupport { @Override @BeforeEach public void setUp() throws Exception { super.setUp(); } @Override protected RoutesBuilder createRouteBuilder() throws Exception { return new TestRoute(); } @Override public boolean isUseAdviceWith() { return true; } @Test void testRoute() throws Exception { AdviceWith.adviceWith(context, null, false, a -> { a.replaceFromWith("direct:start"); a.mockEndpointsAndSkip("*"); }); context.start(); // 此处的false确保使用不存在的模拟端点时会抛出异常,因此这不是问题所在 getMockEndpoint("mock:jpa:Data", false).expectedMessageCount(1); var data = getSomeTestData(); template.sendBody("direct:start", data); assertMockEndpointsSatisfied(); } }
最终通过将a.mockEndpointsAndSkip("*");替换为a.weaveById("testId").replace().to("mock:jpa:Data");解决了问题,但疑惑两者的差异——毕竟mockEndpointsAndSkip("*")理应批量替换所有端点,手动替换在真实复杂场景中会非常繁琐。
两者差异的核心原因
- mockEndpointsAndSkip("*")的匹配逻辑局限:该方法会匹配路由中独立定义的端点URI,但你的路由里,
to("jpa:Data")是包含在testId这个路由节点内的。当你用replaceFromWith("direct:start")替换了起始端点后,原路由的结构发生变化,mockEndpointsAndSkip的通配符匹配逻辑无法正确识别到testId节点内部的to端点,导致没有完成替换。 - weaveById的精准定位逻辑:
weaveById("testId")直接定位到指定ID的路由节点,然后完全替换该节点的输出行为。它不依赖端点URI的匹配,而是直接修改目标节点的逻辑,因此不受路由结构变化的影响,能精准将消息导向mock端点。
让mockEndpointsAndSkip生效的可行方案
如果想继续使用批量替换的方式,有两种调整方向:
- 精准指定端点URI:将通配符
*替换为具体的端点地址,比如mockEndpointsAndSkip("jpa:Data"),避免通配符匹配的歧义,确保目标端点被正确识别。 - 调整路由节点结构:给
to端点单独设置ID,让它成为独立可匹配的节点,例如:
from("jpa:Data") .to("jpa:Data").id("testToJpa");
这样mockEndpointsAndSkip就能准确识别到这个独立的端点节点并完成替换。
另外需要注意:在AdviceWith模式下,mockEndpointsAndSkip必须在路由上下文启动前完成匹配,避免因提前修改路由结构(如replaceFromWith)导致匹配逻辑失效。
内容的提问来源于stack exchange,提问作者Noel93
相关产品推荐
相关产品推荐

