【问题标题】:Apache Camel mock endpointApache Camel 模拟端点
【发布时间】:2015-01-30 22:56:09
【问题描述】:

我最近开始研究 Apache Camel,但遇到了一个问题。 我开始为我的路线编写一些测试,并且有很多示例,其中“到”部分路线写成

    <route id="person-add-route">
        <from uri="direct:start"/>
        <to uri="mock:result"/>
    </route>

所以,我写了一个测试,我希望将 mock:result 作为最后一个端点。

@Test
@DirtiesContext
public void testCamel() throws Exception {
    // Given
    Object body = "body";
    int messageCount = 1;
    MockEndpoint endpoint = getMockEndpoint("mock:result");

    // When
    template.sendBody("direct:start", body);

    // Then
    endpoint.expectedMessageCount(messageCount);
    endpoint.assertIsSatisfied();
}

问题如下:如果我想测试我的路线,写 mock:result 重要吗?

【问题讨论】:

  • 不确定您在问什么...您是在问是否需要在所有路由的末尾包含一个模拟端点以测试它们?
  • 我在问 - 我需要在我的生产路线中包含那个“mock:result”吗?如果是,那对我来说很困惑,因为我不明白为什么我需要在我的真实代码中添加测试功能?有什么办法可以在我的真实代码中排除“模拟:”指令?解决方法对我来说不是问题,但我想获得一些更优雅的解决方案。谢谢,
  • 您做错了,您应该在发送消息之前设置期望。 1) 设定期望 2) 发送消息 3) 断言已满足

标签: java spring apache apache-camel


【解决方案1】:

您无需在生产中包含“mock:result”,有多种方法可以测试您的路线。一种是在您的 Camel 测试中实现 isMockEndpoints

@Override
public String isMockEndpoints()
{
     return "*";
}

所以如果你的路线是这样的:

<route id="person-add-route">
    <from uri="direct:start"/>
    <to uri="direct:result"/>
</route>

您可以像这样检查 MockEndpoint:

MockEndpoint endpoint = getMockEndpoint("mock:direct:result");

您还可以使用AdviceWith 在测试时修改您的路线,方法如下:

context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() {
    @Override
    public void configure() throws Exception 
    {
         weaveAddLast().to("mock:result");
    }
});

此外,正如克劳斯在评论中提到的,请确保在将消息发送到路由之前设置您的期望。

【讨论】:

  • 嗨,实际上,我尝试了您的解决方案,但它不起作用,我收到 DirectConsumerNotAvailableException - 端点上没有可用的消费者。
  • 您需要将direct:result 替换为您实际需要的端点。默认情况下,直接端点需要消费者。我只是在这里作为一个例子。
  • Apache Camel 官方网站可能是最好的资源。克劳斯·易卜生的Camel in Action 书也是一本很好的参考书,但我不确定它的最新程度。
【解决方案2】:

上述(目前已接受)答案非常陈旧,可能不再准确。今天实施类似的方法可能看起来像这样:

给定一个定义为弹簧组件的路由:

import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;
import java.util.Map;

@Component
public class MyRoute extends RouteBuilder {

    @Override
    public void configure() {
        from("direct:start").routeId("myRoute")
            .setBody().simple("${body} world")
            .process(exchange -> 
                exchange.getIn().setHeaders(Map.of("foo", "bar")));
    }
}

那么可以如下测试路由:

import org.apache.camel.CamelContext;
import org.apache.camel.EndpointInject;
import org.apache.camel.Produce;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.component.mock.MockEndpoint;
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.annotation.DirtiesContext;

import static org.apache.camel.builder.AdviceWith.adviceWith;
import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest
@CamelSpringBootTest
@DirtiesContext
class MyRouteTest {

    @Autowired
    protected CamelContext camelContext;

    @Produce("direct:start")
    private ProducerTemplate from;

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

    @Test
    void testMyRoute() throws Exception {
        // arrange
        adviceWith(camelContext, "myRoute", 
            route -> route.weaveAddLast().to("mock:result"));
        mockEndpoint.expectedMessageCount(1);

        // act
        from.sendBody("hello");

        // assert
        mockEndpoint.assertIsSatisfied();
        var result = mockEndpoint.getExchanges().get(0).getIn();
        assertThat(result.getBody()).isEqualTo("hello world");
        assertThat(result.getHeader("foo")).isEqualTo("bar");
    }

}

所以route.weaveAddLast().to("mock:result") 基本上所做的就是将最后一步编织到您的路由,将消息重定向到 mock:result。

【讨论】:

  • 不错!正是我需要的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多