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

如何用MockEndpoint验证Camel路由的重传次数?

解决Apache Camel 4.3.0单元测试重传配置验证问题

一、先纠正核心错误:别禁用错误处理器

你添加的errorHandler(noErrorHandler())是问题根源——这个配置会直接关闭Camel的错误处理机制,重传逻辑完全依赖Error Handler(默认是DefaultErrorHandler)实现,关闭后自然不会触发重传。

二、正确配置重传+单元测试验证步骤

1. 确保路由重传配置绑定到错误处理器

针对TargetServerErrorException的重传规则要正确关联到错误处理器,示例代码:

from("direct:localEndpoint")
    .errorHandler(
        defaultErrorHandler()
            .maximumRedeliveries(2) // 重传2次,总调用次数1+2=3
            .redeliveryDelay(2500)
            .retryOnException(TargetServerErrorException.class)
    )
    .to("mock:targetEndpoint") // 替换为你要测试的目标端点
    .process(exchange -> {
        // 模拟抛出触发重传的异常
        throw new TargetServerErrorException("模拟服务端错误");
    });

2. 单元测试中捕获所有重传消息

默认MockEndpoint只接收最终结果,要捕获每一次重传请求,需开启保留所有交换模式:

@Produce("direct:localEndpoint")
private ProducerTemplate producerTemplate;

@EndpointInject("mock:targetEndpoint")
private MockEndpoint mockEndpoint;

@Test
public void testRedeliveryCount() throws InterruptedException {
    // 开启保留所有消息,包括重传请求
    mockEndpoint.setRetainAllMessages(true);
    
    // 发送测试请求
    producerTemplate.sendBody("测试数据");
    
    // 预期总调用次数:初始1次 + 重传2次 = 3次
    mockEndpoint.expectedMessageCount(3);
    mockEndpoint.assertIsSatisfied();
    
    // 遍历所有交换,获取CamelRedeliveryCounter头
    List<Exchange> exchanges = mockEndpoint.getExchanges();
    for (int i = 0; i < exchanges.size(); i++) {
        Integer counter = exchanges.get(i).getIn().getHeader(Exchange.REDELIVERY_COUNTER, Integer.class);
        // 第一次请求counter为null/0,重传依次为1、2
        System.out.println("第" + (i+1) + "次请求重传计数器:" + counter);
    }
}

三、常见问题排查

  • 拿不到CamelRedeliveryCounter:检查路由中是否有removeHeaders("Camel*")这类操作,会删除Camel系统头;另外确保错误处理器正确触发,头信息是Error Handler在重传时添加的。
  • 重传次数不符:注意maximumRedeliveries(2)是指重传2次,总调用次数是3次,别把重传次数和总次数搞混。
  • 测试超时:单元测试中可以临时把重传延迟改小(比如100ms),或者调用mockEndpoint.await(5000)延长等待时间,避免测试提前结束。

四、生产路由不变的情况下,用AdviceWith做测试

如果不想修改生产路由的配置,可通过AdviceWith在测试时替换目标端点为Mock,保留原错误处理器逻辑:

@Override
protected void configure() throws Exception {
    super.configure();
    adviceWith(context, "localEndpoint", a -> {
        // 替换原生产环境的目标端点为Mock
        a.weaveByToUri("direct:targetServer")
         .replace()
         .to("mock:targetEndpoint");
    });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 15:34:55