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

如何让Camel单元测试适配JUnit的@TestInstance.Lifecycle.PER_CLASS?

解决JUnit 5 PER_CLASS模式下Camel Spring Boot测试失败问题

当切换到TestInstance.Lifecycle.PER_CLASS时,测试类实例仅初始化一次,Camel的MockEndpoint会保留之前的状态配置,同时Spring与Camel的绑定逻辑在单实例模式下无法自动重置端点状态,导致执行测试时出现CamelExecutionException。

以下是两种可行的解决方案:

方案一:重置MockEndpoint状态(推荐)

通过@BeforeEach在每次测试前主动获取并重置MockEndpoint,确保状态干净:

@SpringBootTest
@CamelSpringBootTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@MockEndpoints("mllp:localhost:2575")
class HelloWorldMllpRouterUnitTest {

    @Autowired
    private ProducerTemplate template;

    @Autowired
    private CamelContext camelContext;

    private MockEndpoint mockEndpoint;

    @BeforeEach
    void setUp() {
        // 动态获取MockEndpoint实例
        mockEndpoint = camelContext.getEndpoint("mock:mllp:localhost:2575", MockEndpoint.class);
        // 重置所有状态(包括回复配置、预期消息数等)
        mockEndpoint.reset();
    }

    @Test
    void whenSendBody_thenHelloWorldReceivedSuccessfully() {
        var expectedResponse = "Hello World!";
        mockEndpoint.returnReplyBody(ExpressionBuilder.bodyExpression(String.class, func -> expectedResponse));
        var resp = template.requestBody("mock:mllp:localhost:2575", "Some request body");
        Assertions.assertEquals(expectedResponse, resp);
    }
}

原理说明

  • 放弃@EndpointInject静态注入,改为从CamelContext动态获取端点,避免PER_CLASS模式下注入实例的状态残留。
  • mockEndpoint.reset()会清空所有之前的配置(比如回复规则、断言条件),确保每次测试都是全新的起点。

方案二:使用@DirtiesContext刷新上下文

如果测试场景复杂,重置端点不足以解决问题,可以用@DirtiesContext强制每次测试后重建Spring上下文:

@SpringBootTest
@CamelSpringBootTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@MockEndpoints("mllp:localhost:2575")
@DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
class HelloWorldMllpRouterUnitTest {

    @Autowired
    private ProducerTemplate template;

    @EndpointInject("mock:mllp:localhost:2575")
    private MockEndpoint mockEndpoint;

    @Test
    void whenSendBody_thenHelloWorldReceivedSuccessfully() {
        var expectedResponse = "Hello World!";
        mockEndpoint.returnReplyBody(ExpressionBuilder.bodyExpression(String.class, func -> expectedResponse));
        var resp = template.requestBody("mock:mllp:localhost:2575", "Some request body");
        Assertions.assertEquals(expectedResponse, resp);
    }
}

注意事项

  • 该方式会每次测试后销毁并重建Spring和Camel上下文,测试执行速度会变慢,适合复杂场景下使用。

内容的提问来源于stack exchange,提问作者Andreas Forslöw

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 06:42:46