问题
I need to test Camel routes in a Spring Boot Application. I've the Spring boot main class with all the necessary beans declared in it. I am using the CamelSpringJUnit4ClassRunner.class. Added my Spring boot main class in @ContextConfiguration as it contains all the configurations. I don't have a separate configuration class.
I 've autowired CamelContext in my Test class:
@Autowired
CamelContext camelContext;
But the test fails with the error:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'org.apache.camel.CamelContext' available: expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
回答1:
Try to use the CamelSpringBootRunner.class
as the runner and add the @SpringBootTest
annotation to the test class.
Example from the Camel repository
UPDATE (based on your comment)
If you change your bootstrapper class to SpringBootTestContextBootstrapper
then it should work:
@BootstrapWith(SpringBootTestContextBootstrapper.class)
The equivalent configuration as you have but in this case you don't need to add the ContextConfiguration
and the BootstrapWith
annotation:
@RunWith(CamelSpringBootRunner.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@MockEndpoints("log:*")
@DisableJmx(false)
@SpringBootTest(classes = MyClass.class)
回答2:
With Camel 3.1 Spring Boot 2.2.5 and JUnit5, while also setting test application properties:
@CamelSpringBootTest
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(properties = "spring.cloud.consul.enabled=false")
public class CamelRouteTest {
@Autowired
private TestRestTemplate restTemplate;
@Autowired
private CamelContext camelContext;
@EndpointInject("mock:bean:userService")
private MockEndpoint mockUserService;
private User user;
@BeforeEach
public void setUp() throws Exception {
AdviceWithRouteBuilder.adviceWith(camelContext, "getUsersRoute", a -> {
a.mockEndpointsAndSkip("bean:userService*");
});
user = new User();
user.setId(1);
user.setName("Jane");
mockUserService.returnReplyBody(constant(new User[] {user}));
}
@Test
public void callsRestWithMock() {
ResponseEntity<User[]> response = restTemplate.getForEntity("/rest/users", User[].class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
User[] s = response.getBody();
assertThat(s).contains(user);
}
@Test
public void callsDirectRouteWithMock() throws Exception {
User[] users = DefaultFluentProducerTemplate.on(camelContext)
.to("direct:getusers")
.request(User[].class);
assertThat(users).contains(user);
}
@Test
public void camelStarts() {
assertEquals(ServiceStatus.Started, camelContext.getStatus());
assertThat(camelContext.getRoutes()).hasSizeGreaterThan(0);
}
}
Assuming a RouteBuilder
:
@Component
public class CamelRouter extends RouteBuilder {
@Value("${server.port}")
private int serverPort;
@Override
public void configure() throws Exception {
restConfiguration()
.contextPath("/rest")
.component("servlet")
.apiContextPath("/api-doc")
.port(serverPort)
.bindingMode(RestBindingMode.json)
.dataFormatProperty("prettyPrint", "true");
rest("/users")
.consumes("application/json")
.produces("application/json")
.get()
.outType(User[].class).to("direct:getusers");
from("direct:getusers").routeId("getUsersRoute")
.log("Get users")
.to("bean:userService?method=listUsers");
}
}
and application.yml:
camel:
component:
servlet:
mapping:
context-path: /rest/*
springboot:
name: MyCamel
回答3:
just enable @EnableAutoConfiguration it will work
来源:https://stackoverflow.com/questions/45874617/spring-boot-camel-testing