如何使用 CamelTestSupport 模拟对某些预期对象的响应?

How to mock a response to some expected object using CamelTestSupport?

在构建器方法上创建了一个 DTO(假设它只有一个带有一些随机值的“名称”属性),我想检查返回的对象是否具有相同的值,但响应为空。

单元测试代码:

class GetProductByIdRouteBuilderTest extends CamelTestSupport {

  @Test
  void testRoute() throws Exception {
    var expected = DTOBuilder.getProductDetailsDTO();

    getMockEndpoint("mock:result").expectedMessageCount(1);
    getMockEndpoint("mock:result").expectedHeaderReceived("id", 1);

    var response = template.requestBodyAndHeader(
            "direct:getProductById",
            null,
            "id",
            1L,
            GetProductDetailsDTO.class
    );

    assertMockEndpointsSatisfied();
    assertEquals(expected.getName(), response.getName());
  }

  @Override
  protected RoutesBuilder createRouteBuilder() {
    return new RouteBuilder() {
      @Override
      public void configure() {
        from("direct:getProductById")
            .routeId("getProductById")
            .log("id = ${header.id}")
            .to("mock:result")
        .end();
      }
    };
  }
}

解决方案

使用了 whenAnyExchangeReceived 方法:

getMockEndpoint("mock:result").whenAnyExchangeReceived(exchange -> {
    exchange.getMessage().setBody(expected);
    exchange.getMessage().setHeader(Exchange.HTTP_RESPONSE_CODE, HttpStatus.OK.value());
});

这听起来完全是预料之中的行为,因为原始消息的 body 是 null 并且您的路线不会对其进行转换,因此路线的结果是 null .

让我们逐步描述您的代码以更好地理解:

  1. 测试方法

下一个代码片段向消费者端点 direct:getProductById 发送一条消息,其中 null 作为 body 并且 1L 作为 header id 并尝试将 结果 body 转换为 GetProductDetailsDTO.

类型的 object
var response = template.requestBodyAndHeader(
        "direct:getProductById",
        null,
        "id",
        1L,
        GetProductDetailsDTO.class
);
  1. 路线

您的路由仅记录 header id 的值,并将消费者端点 direct:getProductById 收到的消息按原样 发送到生产者端点 mock:result.


所以知道这一点,我们可以看到您的路线实际上将以 null 作为 body 的消息结束,并且由于 Camel 无法将 null 转换为 object 类型 GetProductDetailsDTO,你的路线结果是 null

我猜你的路线不完整,因为它应该以某种方式查询你的数据库。