Reputation: 1
Want to write a test case for an apache camel wrote I have below, trying to mock the endpoint but am getting a null-pointer when running the test
// SEDA Endpoint Stage Event Driven Architecture
from(Endpoints.SEDA_SEND_ENDPOINT)
.messageHistory()
// Route Name
.routeId(Endpoints.SEDA_SEND_ENDPOINT)
.log("${body}")
// multicast
.multicast()
.parallelProcessing() // create parellel threads
.log("${body}")
// thread pool
.threads()
.executorService(executorService) // specific thread pool
.log("Camel Route Started Message Processing : - ${body}")
// content based routing
.choice()
.when(
CommonUtility
.costIQPredicate) // predicate checking based on the header value to decide the
// route
// .bean(CostIQService.class, "calculatePrice") // // rules engine call
.bean(CostIQPayloadTransformer.class, "payloadTransformer") // payload transformer
// multiple consumer
.to(
Endpoints.SEDA_PROCESS_ENDPOINT, // consumer 1
Endpoints.SEDA_PROCESS_ENDPOINT, // consumer 2
Endpoints.SEDA_PROCESS_ENDPOINT) // consumer 3
.when(CommonUtility.optimizationPredicate)
.bean(OptimizationService.class, "calculatePrice")
.bean(CostIQPayloadTransformer.class, "payloadTransformer")
.to(
Endpoints.SEDA_PROCESS_ENDPOINT,
Endpoints.SEDA_PROCESS_ENDPOINT,
Endpoints.SEDA_PROCESS_ENDPOINT)
.when(CommonUtility.markDownPredicate)
.bean(MarkDownService.class, "calculatePrice")
.bean(CostIQPayloadTransformer.class, "payloadTransformer")
.to(
Endpoints.SEDA_PROCESS_ENDPOINT,
Endpoints.SEDA_PROCESS_ENDPOINT,
Endpoints.SEDA_PROCESS_ENDPOINT)
.when(CommonUtility.pricingPredicate)
.bean(PricingService.class, "calculatePrice")
.bean(CostIQPayloadTransformer.class, "payloadTransformer")
.to(
Endpoints.SEDA_PROCESS_ENDPOINT,
Endpoints.SEDA_PROCESS_ENDPOINT,
Endpoints.SEDA_PROCESS_ENDPOINT)
.log("Final :- ${body}")
.end();
}
Where SEDA_SEND_ENDPOINT = "seda:sendMessage?blockWhenFull=true&concurrentConsumers=100"
and SEDA_PROCESS_ENDPOINT = "seda:processMessage?blockWhenFull=true"
I have written this test case but I am getting a null pointer exception, I don't think it is picking up my route.. am I calling it correctly?
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.HashMap;
import java.util.Map;
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit5.CamelTestSupport;
import org.apache.camel.test.spring.junit5.MockEndpoints;
import org.junit.jupiter.api.Test;
import org.apache.camel.EndpointInject;
import org.apache.camel.Exchange;
import org.apache.camel.Predicate;
import org.apache.camel.Processor;
import org.apache.camel.ProducerTemplate;
//@SpringBootTest
// @RunWith(CamelSpringBootRunner.class)
@MockEndpoints("seda:processMessage")
public class CamelRouteTests1 extends CamelTestSupport {
@EndpointInject(uri = "mock:seda:processMessage")
MockEndpoint mock;
@Autowired
ProducerTemplate template;
@Test
public void testMethod() throws InterruptedException {
mock.expectedBodiesReceived("test");
template.sendBody("seda:sendMessage", "test");
mock.assertIsSatisfied();
}
}
Upvotes: 0
Views: 1197
Reputation: 2167
When using spring annotations your test class should not inherit from CamelTestSupport
and it should include the @SpringBootTest
and @RunWith(CamelSpringBootRunner.class)
annotations you've commented out. CamelSpringBootRunner
should be able to pick up any classes with @Component
annotation that implement RouteBuilder
interface for your tests.
CamelTestSupport
is generally used for testing camel routes in applications that do not use any of the application frameworks supported by Camel. To use it you'll need to override at least the createRouteBuilder
or the createRouteBuilders
method to return RouteBuilder(s) to run tests against.
As far as I know the CamelTestSupport
doesn't support @EndpointInject
, @Autowired
or @MockEndpoints
spring-annotations so I would advice against mixing the two.
Your null-pointer exception is probably caused by both mock
and template
being null since @EndpointInject
and @Autowired
annotations will do nothing with @SpringBootTest
and @RunWith(CamelSpringBootRunner.class)
commented out.
[Edit]
In newer Camel versions like Apache camel 3.15.0 you should use annotations @SpringBootTest
and @CamelSpringBootTest
for the test class instead. Requred imports are org.apache.camel.test.spring.junit5.CamelSpringBootTest
and org.springframework.boot.test.context.SpringBootTest
.
Also make sure that the import for @Test annotation is org.junit.jupiter.api.Test
and NOT import org.apache.camel.test.junit5.params.Test
.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test-spring-junit5</artifactId>
<scope>test</scope>
</dependency>
Instead of specifying all the versions yourself you should use camel and spring-boot BOM:s instead. These go to the dependencyManagement section in your pom. These should provide you with compatible versions of dependencies.
<dependencyManagement>
<dependencies>
<!-- Spring Boot BOM -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.6.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Camel BOM -->
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-dependencies</artifactId>
<version>3.15.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
You can use maven to generate example projects for different versions of camel. These usually come with pretty good examples on how to setup basic camel integration with unit tests.
mvn archetype:generate "-DarchetypeGroupId=org.apache.camel.archetypes" "-DarchetypeArtifactId=camel-archetype-spring-boot" "-DarchetypeVersion=3.15.0"
Upvotes: 1