6

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)}

dschulten
  • 2,994
  • 1
  • 27
  • 44
Mittal
  • 105
  • 3
  • 12

3 Answers3

9

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) 
mgyongyosi
  • 2,557
  • 2
  • 13
  • 20
  • Thank you.The below exception is still there. – Mittal Aug 26 '17 at 10:57
  • Can you post the relevant part from your test class (class declaration, ContextConfiguration settings)? – mgyongyosi Aug 26 '17 at 11:02
  • 2
    @RunWith(CamelSpringJUnit4ClassRunner.class) @BootstrapWith(CamelTestContextBootstrapper.class) @ContextConfiguration(MyClass.class) @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) @MockEndpoints("log:*") @DisableJmx(false) public class CamelSpringJUnit4ClassRunnerPlainTest { @Autowired protected CamelContext camelContext; ......... } Let MyClass be my SpringBoot start up class with the main method and all the other beans defined in it. – Mittal Aug 27 '17 at 06:32
  • 1
    I tried with the @SpringBootTest .But its still throwing exception on autowiring CamelContext. – Mittal Aug 27 '17 at 06:41
  • facing the same issue. – Atul Agrawal Dec 07 '20 at 13:31
  • Same here but using JUnit5 – Marian Klühspies Feb 23 '21 at 10:03
4

just enable @EnableAutoConfiguration it will work

4

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
dschulten
  • 2,994
  • 1
  • 27
  • 44