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

492 views Asked by At

There's a DTO created on a builder method (assume it has only a "name" attribute with some random value) and I want to check if the returned object has the same value, but the response is null.

Unit test code:

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();
      }
    };
  }
}

Solution

Used the whenAnyExchangeReceived method:

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

There are 1 answers

1
Nicolas Filotto On BEST ANSWER

It sounds like a totally expected behavior since the body of the original message is null and your route doesn't transform it such that the result of your route is null.

Let's describe your code step by step to better understand:

  1. The test method

The next code snippet, sends a message to the Consumer endpoint direct:getProductById with null as body and 1L as value of the header id and tries to convert the resulting body into an object of type GetProductDetailsDTO.

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

Your route simply logs the value of the header id and sends the message received by the consumer endpoint direct:getProductById as is to the producer endpoint mock:result.


So knowing that, we can see that your route will actually end with a message with null as body, and since Camel cannot convert null to an object of type GetProductDetailsDTO, you end up with null as result of your route.

I guess that your route is incomplete as it should somehow query your database.