This might be a little simplistic but I normally set up test routes for my
processors and then send exchanges directly to them with the expected
Exchange structure for them to process.

So for example, I have a processor named CsvProcessor.  It expects to
receive a Map<String,String> from the Marshaller of a CSV File: (Note, I
normally register my processors as Beans in a Spring Configuration class,
you can use component annotations to get the same effect)

public class CsvProcessor implements Processor {

  @SuppressWarnings("unchecked")
  @Override
  public void process(Exchange exchange) {

    Map<String, String> row = exchange.getMessage().getBody(Map.class);
    exchange.getMessage().setHeader("RowId", row.getOrDefault("Id", "0"));
    exchange.getMessage().setBody(row.getOrDefault("Name", "None"));
  }
}

To Test is, I will setup a Test Route for my unit tests like the following:

@Component
public class CsvProcessorTestRoute extends RouteBuilder {
  @Override
  public void configure() {

    from("direct:csv-input")
        .routeId("csv-processor-test-route")
        .bean(ProcessorConstants.CSV_PROCESSOR)
        .to("mock:csv-output")
        .end();

  }
}


Then I can use this route directly in my Unit Tests to send an Exchange to:

@ExtendWith(SpringExtension.class)
@SpringBootTest
class CsvProcessorTest {

  @EndpointInject("direct:csv-input")
  ProducerTemplate template;

  @EndpointInject("mock:csv-output")
  MockEndpoint output;

  @Test
  @DirtiesContext
  void testCsvProcessor() {
    Map<String, String> row = new HashMap<>();
    row.put("Id", "1");
    row.put("Name", "Jim Smith");

    var exchange = ExchangeBuilder.anExchange(template.getCamelContext())
        .withBody(row)
        .build();
    template.send(exchange);

    assertThat(output.getExchanges()).as("Output should not be
empty").isNotEmpty();

    var msg = output.getExchanges().get(0);

    assertThat(msg.getMessage().getHeader("RowId"))
        .as("Row Id should be in the Header")
        .isEqualTo("1");
    assertThat(msg.getMessage().getBody())
        .as("Body should be the name")
        .hasToString("Jim Smith");
  }
}

I'm sure there are a number of ways to accomplish this problem, but this is
how I've tackled this with pretty positive success.  I've placed this
sample project on GitHub at the link below.
https://github.com/openbatch/camel-unit-testing

Hope this helps!

On Fri, Mar 4, 2022 at 6:58 AM Alaeddine HAOUAS <4codynam...@gmail.com>
wrote:

> Hi,
>
> I have an issue in a unit test, to verify a Processor.
> Context is a Spring-boot application used to control a Camel route, that
> triggers eventually a Camel processor.
>
> In a JUnit test, I achieved to have the RouteBuilder started and tested
> successfully until the instruction setting up the Processor. Processor is
> not starting, so I can't verify it.
>
> How can I successfully trigger/test the processor ?
>
> The code :
>
> @Component
> public class CsvRouteBuilder extends RouteBuilder {
> //....
>
> private void process(.....) {
>         // .....
>
>         String fromRoute = String.join("", "file:",
> orgParPath.toAbsolutePath().toString(),
>                 "?moveFailed=", ERROR, "&move=", ARCHIVE, "&delay=",
>                 delayIntervalMilliSec);
>
>         // initializing the context
>
>         final Processor processor =
> CsvProcessor.builder().csvExecutionContext(context)
>                 .csvHdConnectProxyRestTemplate(hdConnectProxy)
>                 .executorService(executorService).build();
>
>         from(fromRoute).unmarshal().csv().process(processor);
> }
>
> //.... another class
> @Builder
> public class CsvProcessor implements Processor {
> // ...
> // The custom processor has nothing exotic, it is just implementing the
> process method.
> }
>
> //.... another class
> @ExtendWith(SpringExtension.class)
> @CamelSpringBootTest
> @UseAdviceWith
> @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
> classes = Application.class)
> @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class,
> HibernateJpaAutoConfiguration.class})
> @DisableJmx
> @ContextConfiguration(classes = {TestConfig.class})
> @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
> public class CsvRouteBuilderTest {
>
>     @Autowired
>     ProducerTemplate producerTemplate;
>
>     @Autowired
>     private TestRestTemplate restTemplate;
>
>     @Autowired
>     private CsvRouteBuilder route;
>
> // ....
> }
>
> Regards
> Alaeddine
>

Reply via email to