Camel/RabbitMQ路由单元测试问题:消息未达目标队列
我之前也碰到过类似的Camel单元测试难题,尤其是用adviceWith替换RabbitMQ队列做隔离测试时,遇到断言失败真的挺挠头的。咱们一步步梳理可能的问题点和解决办法:
确认
adviceWith的端点匹配是否精准
你需要确保替换的目标URI和路由里实际使用的RabbitMQ端点完全一致,或者用更灵活的匹配规则覆盖到目标端点。比如如果原路由里的RabbitMQ端点是rabbitmq://localhost:5672/my-exchange?queue=INPUT_QUEUE,那替换时要精准命中这个URI,或者用rabbitmq:*匹配所有RabbitMQ端点:context.getRouteDefinition("your-target-route-id") .adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // 替换指定RabbitMQ端点为mock weaveByUri("rabbitmq://localhost:5672/my-exchange?queue=INPUT_QUEUE") .replace().to("mock:input-queue"); // 或者替换所有RabbitMQ端点 weaveByUri("rabbitmq:*").replace().to("mock:all-rabbitmq-endpoints"); } });检查MOBILE_QUEUE对应的MockEndpoint断言配置
如果你直接断言mock:MOBILE_QUEUE的消息数量,一定要确保提前创建了这个MockEndpoint并设置了正确的预期值,比如:// 获取MockEndpoint实例 MockEndpoint mobileMock = context.getEndpoint("mock:MOBILE_QUEUE", MockEndpoint.class); // 设置预期收到的消息数量 mobileMock.expectedMessageCount(1); // 发送测试消息到路由入口 template.sendBody("direct:your-route-entry", "test-payload"); // 验证断言是否满足 mobileMock.assertIsSatisfied();排查路由逻辑是否拦截了消息
路由里可能存在choice()分支、filter()过滤器或者transform()处理,导致消息没有流向MOBILE_QUEUE。可以在路由的关键节点临时添加mock端点,跟踪消息流向:// 在路由中间插入mock,验证消息是否到达该节点 weaveAddLast().to("mock:route-middle-stage");然后断言这个中间mock的消息数量,逐步定位是哪一步出了问题。
确保
adviceWith在路由启动前执行
一定要在调用context.start()之前执行adviceWith,否则路由已经初始化完成,端点替换不会生效。正确的执行顺序是:// 1. 初始化Camel上下文 DefaultCamelContext context = new DefaultCamelContext(); // 2. 添加目标路由 context.addRoutes(new YourRouteBuilder()); // 3. 执行adviceWith替换端点 context.getRouteDefinition("your-target-route-id").adviceWith(context, ...); // 4. 启动上下文 context.start();开启调试日志排查异常
有时候消息丢失是因为路由执行过程中抛出了异常但被吞掉了,你可以开启Camel的DEBUG级日志,查看消息的每一步处理细节:@BeforeClass public static void setupDebugLogging() { System.setProperty("org.apache.camel.logger.level", "DEBUG"); }从日志里你能看到消息是否被正确转发、有没有报错或者被过滤掉。
内容的提问来源于stack exchange,提问作者Kaigo

