java - Apache Camel - 定义在管道上没有子项

标签 java apache-camel

这是我的简单路线:

@Override
public void configure() {

onException(Exception.class)
    .handled(true)
    .process(exchange -> {
      Exception exception = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);
      log.error(logFormat.error(exchange, exception, exception.getMessage()));
      exchange.getIn().setBody(exception.getMessage());
      exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, HttpStatus.SC_INTERNAL_SERVER_ERROR);
    });

onException(HttpOperationFailedException.class)
    .handled(true)
    .to("direct:handleHttpOperationFailed");

from("direct:myRoute")
    .routeId("myRoute")
    .log("Route start: myRoute")
    .id("startStep")
    .process(
        exchange -> log.info("Doing some processing")
    )
    .id("processingStep")
    .end();
}

现在我想编写一些测试:

  1. 异常处理案例 - 在“processingStep”之后抛出异常并在 onException 中处理
  2. 积极场景 - 所有流程均顺利进行

这就是我所做的......

我的测试注释:

@RunWith(CamelSpringBootRunner.class)
@UseAdviceWith
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class StarlingFpsInboundWebhookIT {
   ...
}

我的两个测试用例:

  1. 有异常情况 - 这里我使用adviceWith在“processingStep”之后抛出异常:
@Test
public void exceptionScenario() throws Exception {

    // Given
    context.getRouteDefinition("myRoute").adviceWith(context, new AdviceWithRouteBuilder() {
      @Override
      public void configure() {
        weaveById("processingStep").after()
            .process(exchange -> {
              throw ExceptionFixtures.createSimpleException();
            })
            .id("exceptionThrowStep");
      }
    });
    context.start();

    String requestBody = ResourcesHelper.read(this.getClass(), "/data/input/request.json");

    // When
    template.send("direct:myRoute", camelExchange -> {...});
}
  • 成功案例 - 这里我需要删除之前创建的“exceptionThrowStep”以免抛出异常:
  • @Test
    public void successScenario() throws Exception {
    
        // Given
        context.getRouteDefinition("myRoute").adviceWith(context, new AdviceWithRouteBuilder() {
          @Override
          public void configure() {
            weaveById("exceptionThrowStep").remove();
          }
        });
        context.start();
    
    
        String requestBody = ResourcesHelper.read(this.getClass(), "/data/input/request.json");
    
        // When
        template.send("direct:myRoute", camelExchange -> {...});
    }
    

    当我运行这些测试时(第一个异常然后成功的场景),我在第二个测试中遇到异常:

    org.apache.camel.FailedToCreateRouteException: 
    Failed to create route myRoute at: 
    >>> pipeline -> [[]] <<< 
    in route: Route(myRoute)[[From[direct:myRoute]... 
    because of Definition has no children on pipeline -> [[]]
    

    为什么会出现这个异常?我读过很多文章,但没有发现任何关于这个案例的宝贵信息:( 有趣的是-当在adviceWith的第二次测试中我使用replace()而不是remove()时,一切正常......

    我的问题是:

    1. 在路由中测试异常处理是一种好方法吗?
    2. 我们可以在测试之间重置路由定义来避免我的方法吗?

    最佳答案

    最后我从你的两个问题开始:

    1. 是的,最好也测试路线的错误路径,而不仅仅是快乐路径
    2. 是的,您可以并且应该在测试之间重置路由定义。由于您运行 SpringBootTest,您可以使用 DirtiesContext annotation 来完成此操作。 (Spring 测试框架的一部分)

    示例:

    @Test
    @DirtiesContext
    public void successScenario() throws Exception {
    

    运行带注释的测试后,默认情况下会重置 Camel 路由。

    您的测试不得依赖于特定顺序才能成功运行!这会导致测试结果不稳定并降低您对测试的信心。

    一般来说,您的成功测试不需要任何路由修改,因为这是预期的处理路径。对于错误测试,您必须在路由中注入(inject)错误(就像使用adviceWith 一样)以模拟处理错误。

    关于java - Apache Camel - 定义在管道上没有子项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62290721/

    相关文章:

    java - 使用 Maven 编译并执行 JDK 预览功能

    regex - 是否可以通过 Spring DSL 替换字符串中的双引号“字符?

    java - 如何从 Apache Camel 调用带有 BODY 内容的 Rest API DELETE 操作?

    java - Camel AWS SQS Cron Scheduler集成问题

    java - 如何在通过 Camel 调用 Restful 服务时添加 jks 文件

    apache-camel - 使用状态码 405 获取 org.apache.camel.component.http.HttpOperationFailedException

    java - java.lang.Object 怎么可能用 Java 实现?

    java - 使用两个不同版本的程序读取/写入相同的 csv

    java - 什么是静态变量

    java - 在 JPA 中以多对多关系编写计数聚合函数会引发 Hibernate 错误