Integration Test
The integration test is a special form of testing where you usually start a complete Apache Camel application to verify its interaction with other components and services.
A typical integration test scenario verifies the collaboration of services and their integration with each other. Usually this includes infrastructure in particular data persistence layers, message brokers or 3rd party services.
Both unit testing and integration testing are essential in software development to ensure the functionality and the compatibility with integrated services. The combination of both results in a successful quality assurance of your Camel application. |
Citrus test framework
As an example of writing integration tests for Camel applications you can use the Citrus test framework. Citrus is an Open Source Java testing framework with focus on integration testing and messaging.
The framework provides a very good integration with Apache Camel. Citrus helps you to write automated integration tests with a proper preparation of test infrastructure and connects with the exposed services to verify the Camel application with powerful message validation capabilities for different message data formats (e.g. XML, Json, YAML, plaintext).
Please refer to the Citrus documentation to find out how to write automated tests for Apache Camel applications. The following sections might be interesting to explore for Camel developers and testers:
Name | Description |
---|---|
Start and stop Camel routes as part of the test. | |
Start and stop Camel test infrastructure services as part of the Citrus test. | |
Use Camel processor, transformer and data format EIPs in Citrus tests. | |
Run Camel integrations with JBang as part of a test. |
Citrus provides a good integration with JBang and Camel JBang. This means you can use Citrus from the very beginning for writing automated tests also in the prototyping phase with Camel JBang. Read about it in the chapter Camel JBang test plugin. |
Citrus integrates with Quarkus and Spring Boot so you can write the tests on top of known concepts and libraries. You can choose from a set of supported test engines such as JUnit Jupiter to run the tests as part of the build lifecycle or from your favorite IDE.
Quarkus Test support
When writing applications with Quarkus you will most likely use the @QuarkusTest
or @QuarkusIntegrationTest
annotated JUnit Jupiter classes. You can continue to use this in combination with Citrus in order to write automated integration tests for your application.
The following example uses the Citrus Quarkus extension in a Quarkus test:
@QuarkusTest
@CitrusSupport
public class CamelDemoApplicationIT implements TestActionSupport {
@BindToRegistry
private final HttpClient httpClient = HttpEndpoints.http()
.client()
.requestUrl("http://localhost:8081")
.build();
@BindToRegistry
private final KafkaEndpoint completed = new KafkaEndpointBuilder()
.topic("completed")
.build();
@CitrusResource
private TestCaseRunner t;
@Test
void shouldVerifyDemoApp() {
t.given(
http().client(httpClient)
.send()
.post("/bookings")
.message()
.body(Resources.fromClasspath("booking.json"))
);
t.when(
http().client(httpClient)
.receive()
.response(HttpStatus.OK)
);
t.then(
receive().endpoint(completed)
.message()
.body("Booking complete!")
);
}
}
Citrus comes with a Quarkus extension that provides the @CitrusSupport
annotation. Once added to your test class the test is able to use the Citrus endpoint components as well as the Java domain specific language for writing integration tests.
The example above uses the normal @QuarkusTest
annotation to start the Camel application. Then the test then uses Citrus endpoints to interact with the exposed Http service and invokes an endpoint /bookings
with a given booking.json
payload. The expected result is a 200 OK response as well as an event message on the Kafka topic completed
. Both response and event content is verified with an expected message content (e.g. Http status 200 OK).
The class names that represent integration tests use the suffix *IT . This is a common design principle in order to separate normal unit tests and integration tests. Unit tests usually use the *Test name suffix. The Maven build lifecycle is able to separate the test categories by their names so the Maven surefire plugin is able to run unit tests in the test lifecycle phase while the Maven failsafe plugin runs integration tests in the integration-test Maven lifecycle phase. |
Always make sure to use one of the naming patterns for unit or integration tests, so Maven is able to find and execute your tests in the respective build lifecycle phase. |
Spring Boot support
You can use Citrus in your Spring Boot tests very easily to interact with the Apache Camel routes started as part of the Spring Boot application.
The following example uses the Citrus Quarkus extension in a Quarkus test:
@SpringBootTest(classes = CamelDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@CitrusSpringSupport
@ContextConfiguration(classes = { CitrusEndpointConfig.class })
public class CamelDemoApplicationIT implements TestActionSupport {
@Autowired
private HttpClient httpClient;
@Autowired
private KafkaEndpoint completed;
@CitrusResource
private TestCaseRunner t;
@Test
void shouldVerifyDemoApp() {
t.given(
http().client(httpClient)
.send()
.post("/bookings")
.message()
.body(Resources.fromClasspath("booking.json"))
);
t.when(
http().client(httpClient)
.receive()
.response(HttpStatus.OK)
);
t.then(
receive().endpoint(completed)
.message()
.body("Booking complete!")
);
}
}
Citrus comes with a Spring integration which means that you can declare Citrus endpoints as Spring beans. The Citrus Spring support is enabled on the test with the @CitrusSpringSupport
JUnit annotation.
Once added to your test class the test is able to use the Citrus endpoint components as well as the Java domain specific language for writing integration tests.
The example above uses the normal @SpringBootTest
annotation to start the Camel application. Then the test then uses autowired Citrus endpoints to interact with the exposed Http service and invokes an endpoint /bookings
with a given booking.json
payload. The expected result is a 200 OK response as well as an event message on the Kafka topic completed
. Both response and event content is verified with an expected message content (e.g. Http status 200 OK).
The Citrus endpoint beans are defined in a Spring configuration class CitrusEndpointConfig
.
@Configuration
@Import(CitrusSpringConfig.class)
public class CitrusEndpointConfig {
@Bean
public HttpClient httpClient() {
return http().client()
.requestUrl("http://localhost:8080")
.build();
}
@Bean
public KafkaEndpoint completed() {
return kafka()
.topic("completed")
.build();
}
}
The class names that represent integration tests use the suffix *IT . This is a common design principle in order to separate normal unit tests and integration tests. Unit tests usually use the *Test name suffix. The Maven build lifecycle is able to separate the test categories by their names so the Maven surefire plugin is able to run unit tests in the test lifecycle phase while the Maven failsafe plugin runs integration tests in the integration-test Maven lifecycle phase. |
Always make sure to use one of the naming patterns for unit or integration tests, so Maven is able to find and execute your tests in the respective build lifecycle phase. |