Bruno Carneiro
Bruno Carneiro

Reputation: 343

How to test this Camel Route? Dependence Injection and Enviroment Variables

I have two doubts:

a. How to mock the http4 compoenent in a way that my route does not know when it is mocked and when it is real?

b. How to initialize myDestinationEndpoint when running tests?

package my.package

@Component
public class MyRoute extends RouteBuilder {
    @Value("${MY_DESTINATION_ENDPOINT}")
    private String myDestinationEndpoint;

    from("direct:my-route")
        .split()
            .method(MyBean.class,"split") //splits the message in two messages. One will pass and other will be redirect to http4
            .aggregationStrategy(MyBean.aggregator()) //After redirect to http4, the response will be added to the first message and continue to the next route.
                .choice()
                    .when().method(MyBean.class,"shouldRedirect")
                        .to("http4:" + myDestinationEndpoint + "?bridgeEndpoint=true") //How to mock here???
                        .unmarshal(new JacksonDataFormat(Object.class))
                 .end()
            .end()
    ;
}

What a have tried?

a. In order to Mock, I have found the component"mock". But in this case, I am hard coding the mock in the route. To me it is like I have one test code, with mock, to run in test enviroment and other similar code without mock to run in production. But, for my understanding, the test code should be the same production code.

.when().method(MyBean.class,"shouldRedirect")
    .to("mock:" + myDestinationEndpoint)

I expected that the mock worked as an interface and in the production I should inject a real object and in test I should inject a fake/mock object.

b. As I was stucked in the step a. I have not much time to investigate this. When running em my localhost, I set myDestinationEndpoint as a Java Program Argument, in eclipse. When running em QA and PRD, I use a configmap file (.yml).

EDIT: Trying to implement ShellDragon's suggestion.

I have implemented this test class and I got this error:

org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.

I added the FirstTest.properties file in the /src/test/resources and /src/test/resources/my/package

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@ContextConfiguration(classes = AgenciaInternalRoute.class) //Classe que contém valores a serem injetados
@TestPropertySource //flag que faz com que a classe indicada em @ContextConfiguration receba os valores de um arquivo de propriedades
public class FirstTest extends CamelTestSupport {

    @Autowired
    private TestRestTemplate restTemplate;


    @Override
    protected RouteBuilder createRouteBuilder() throws Exception{
        return new MyRoute();
    }

    @Test
    public void simpleTest() {

    }
}

Upvotes: 0

Views: 990

Answers (1)

ShellDragon
ShellDragon

Reputation: 1722

You can use adviseWith to intercept exchange deliveries to http4 endpoint and reroute it to a mock: endpoint instead, during test execution. Original code can stay exactly as is. Please have a look at the test case here. If you are using Camel 3.x, the API has changed, please refer to this test case instead.

To mock @Value annotation, use TestPropertySource annotation in Spring and run your test class with an appropriate runner, like SpringJUnit4ClassRunner. No additional hack from command line will be required if you use TestPropertySource

Upvotes: 3

Related Questions