Spring测试中如何使用adviceWith测试Camel XML路由?
解决Camel XML路由的adviceWith测试配置问题
首先看你代码里的明显错误:XML路由的ID是ww-inbound,但测试里你用了rot-ww-inbound去获取路由定义,这会导致找不到路由,先把这个ID修正。
接下来,因为你的路由是Spring XML格式定义的,不能直接用纯Camel的CamelTestSupport,需要集成Spring上下文来加载XML路由,以下是两种可行的配置方案:
方案一:使用CamelSpringTestSupport(传统Spring项目)
步骤1:切换测试基类
把测试类的父类从CamelTestSupport改成CamelSpringTestSupport,这个类专门用于Spring集成的Camel测试。
步骤2:加载Spring上下文与路由XML
重写createApplicationContext方法,加载你的路由XML文件,以及所需的Bean配置文件(比如包含inbound.IntegrationHeaders等Bean的配置)。同时配置属性占位符,解决XML里的{{...}}属性引用。
完整测试代码示例
import static org.apache.camel.builder.AdviceWith.adviceWith; import org.apache.camel.test.spring.CamelSpringTestSupport; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.core.io.ClassPathResource; class InboundRouteTests extends CamelSpringTestSupport { @Override public boolean isUseAdviceWith() { return true; } // 配置属性占位符,提供测试用的属性值 @Override protected PropertySourcesPlaceholderConfigurer createPropertyPlaceholderConfigurer() { PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer(); configurer.setLocation(new ClassPathResource("test-application.properties")); return configurer; } // 加载Spring上下文,包含路由XML和Bean配置 @Override protected AbstractApplicationContext createApplicationContext() { return new ClassPathXmlApplicationContext( "classpath:your-route-definition.xml", // 你的XML路由文件路径 "classpath:inbound-beans.xml" // 包含inbound相关Bean的配置文件 ); } @Test void doTest() throws Exception { // 修正路由ID为XML里的ww-inbound RouteDefinition route = context.getRouteDefinition("ww-inbound"); adviceWith(route, context, advice -> { // 替换原from端点为mock advice.replaceFromWith("mock:newStart"); // 还可以mock其他外部端点,比如rabbitmq和file组件 advice.mockEndpoints("rabbitmq:*", "file:*"); }); // 启动上下文(因为isUseAdviceWith为true,上下文会延迟启动) context.start(); // 发送测试消息 template.sendBody("mock:newStart", "Some text"); // 验证mock端点是否收到消息,或者其他业务逻辑验证 getMockEndpoint("mock:newStart").expectedMessageCount(1); assertMockEndpointsSatisfied(); } }
测试属性文件示例(test-application.properties)
ww.mail.server=mock:mail ww.mail.username=test-user ww.mail.password=test-pass ww.mail.consumer.delay=5000 ww.incoming.fs.slug=/tmp/test-incoming amqp.main.queue=test-queue
方案二:使用Spring Boot测试注解(Spring Boot项目)
如果你的项目是Spring Boot,用以下方式更简洁:
测试代码示例
import static org.apache.camel.builder.AdviceWith.adviceWith; import org.apache.camel.CamelContext; import org.apache.camel.RouteDefinition; import org.apache.camel.test.spring.junit5.CamelSpringBootTest; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.TestPropertySource; @SpringBootTest @CamelSpringBootTest @TestPropertySource(locations = "classpath:test-application.properties") class InboundRouteTests { @Autowired private CamelContext context; @Autowired private ProducerTemplate template; @Test void doTest() throws Exception { RouteDefinition route = context.getRouteDefinition("ww-inbound"); adviceWith(route, context, advice -> { advice.replaceFromWith("mock:newStart"); advice.mockEndpoints("rabbitmq:*", "file:*"); }); // 启动路由(Spring Boot下需要手动启动被adviceWith修改的路由) context.startRoute("ww-inbound"); template.sendBody("mock:newStart", "Some text"); getMockEndpoint("mock:newStart").expectedMessageCount(1); assertMockEndpointsSatisfied(); } }
关键注意点
- 路由ID匹配:确保测试中获取路由的ID和XML里的
id="ww-inbound"完全一致。 - 延迟启动上下文:因为使用
adviceWith,必须让Camel上下文延迟启动(isUseAdviceWith()返回true),这样才能在启动前修改路由。 - Bean依赖:确保测试上下文能加载路由中引用的所有Bean(
inbound.IntegrationHeaders、inbound.Converter等),要么在XML配置里定义,要么用@Component注解让Spring扫描到。 - 属性占位符:必须提供测试用的属性值,避免因为找不到属性导致上下文加载失败。
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

