Apache Camel: Mock & Testing
In this post, we are going to see how to test the routes we develop with Apache Camel. We will also see several components and best practices that we can use to improve not only our tests but also our code. Keep in mind that we will use JUnit 5 to perform the tests.
To begin with, we will start with the necessary library to perform the tests, as we are going to develop our application with Spring Boot, we need the testing dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test-spring-junit5</artifactId>
<scope>test</scope>
</dependency>
The next step is to create our test. And as we have indicated, Apache Camel will provide us with annotations and utilities that will allow us to carry out our tests. Here are some of them:
- @CamelSpringBootTest: Annotation needed to test Apache Camel applications with Spring Boot.
- @EnableAutoConfiguration: It will allow using the Spring context with an automatic configuration, in addition, to enable the Apache Camel context.
- @SpringBootTest: Allows to configure the Spring context and also to indicate properties of this context, specific for the test.
- ProducerTemplate: Interface that allows the exchange of messages to endpoints in different ways. The send methods are only input and the request methods are input/output.
- Mock: Specific testing endpoint that also allows checking incoming messages: number of messages, content, etc.
- Direct: Stub that allows invoking routes directly without the need to invoke them through a specific access protocol.
- Seda: Stub that simulates an asynchronous queue and allows several subscribers.
As we have seen in the previous example, with these seven elements we will be able to perform many types of tests and improve the coverage of the Apache Camel applications. But now we will see how to test not simply mocks or routes made ad-hoc for our tests, but those routes that we develop and will be deployed. For example, the following route:
If we try to test this endpoint we would need to perform HTTP invocations, testing not only the logic but also how we make the connection to the endpoint. This would no longer be unit tests, but integration tests. To be able to perform unit tests, it is a good practice to divide the logic into elements that allow us to validate the logic more easily. Therefore our route would be as follows:
rest().get("book").produces(MediaType.APPLICATION_JSON_VALUE).to("direct:restGetAllBooks");
from("direct:restGetAllBooks").bean(BookMockRouter.class, "getAll(})").marshal().json();
Once the refactoring is done, we will be able to test this new route. But for this we will also have to configure the route in the test, as follows:
Finally, we will see a good practice for our developments and that can also help us testing. And this is the parameterization of our endpoints. For this, we would have to make three changes in our code, which will be applied to a new endpoint.
The first change is to create the endpoint to be accessed through a variable.
The second change is to indicate in the application.properties file the value of this variable. In this case, it will be fixed in all environments, but the use of variables allows us to develop in which the input or output endpoints are dynamic.
# Routes
rest.get.libro.id=rest:GET:/libro/{id}
Finally, in our test file we indicate that to carry out the tests, this dynamic endpoint will not be invoked through HTTP but through the Direct component. This can be done through the @SpringBootTest annotation. The rest of the test will be similar to what we already have.
An alternative to the use of variables can be to use the adviceWith component. But I think that for development and testing purposes it is better to use variables.
I hope it has been useful and helps you in the improvement of Apache Camel testing. As always, you can find the source code here.