测试期间丢失骆驼交换头

时间:2018-08-12 10:14:41

标签: apache-camel integration-testing

我正在尝试在下面的类中测试onException(JsonProcessingException.class)路由(请不要介意它的名称,为清晰起见,我已经删掉了一些代码):

import org.apache.camel.Exchange;
import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.model.rest.RestBindingMode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonProcessingException;

import pl.muni.camel.sample.customer.domain.CustomerData;
import pl.muni.camel.sample.customer.route.processor.CreateCustomerErrorResponseProcessor;
import pl.muni.camel.sample.customer.route.processor.CreateCustomerOkResponseProcessor;

@Component
public class SendCustomerDataToQueueRoute extends RouteBuilder {

    @Value("${http.rest.listener.host}")
    private String restListenerHost;

    @Value("${http.rest.listener.port}")
    private int restListenerPort;

    @Override
    public void configure() {
        restConfiguration()
            .component("restlet")
            .dataFormatProperty("prettyPrint", "true")
            .host(restListenerHost)
            .port(restListenerPort);

        rest("/rest/v1/customer")
            .post("/create")
            .bindingMode(RestBindingMode.json)
            .skipBindingOnErrorCode(false)
            .consumes("application/json")
            .type(CustomerData.class)
            .produces("application/json")
            .route().id("acceptCreateCustomerRequest")
            .from("direct:acceptRequest")
            .to("direct:processRequest");

        onException(JsonProcessingException.class)
            .handled(true)
            .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(400))
            .to("direct:processException");

        onException(Exception.class)
            .handled(true)
            .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(500))
            .to("direct:processException");

        from("direct:processRequest").routeId("processCreateCustomerRequest")
            .log("Received customer data: ${body}")
            .process(new CreateCustomerOkResponseProcessor()).id("createOkResponse");

        from("direct:processException").routeId("processCreateCustomerException")
            .log(LoggingLevel.ERROR, "${exception.stacktrace}").id("logExceptionStackTrace")
            .process(new CreateCustomerErrorResponseProcessor()).id("createErrorResponse");
    }
}

我想在createErrorResponse处理器之后拦截交换并在其上运行一些断言。到目前为止,我已经提出了以下代码,其中在direct:processException端点之后编织了一个模拟端点:

import java.util.List;

import org.apache.camel.CamelContext;
import org.apache.camel.EndpointInject;
import org.apache.camel.Exchange;
import org.apache.camel.Produce;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.AdviceWithRouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.spring.CamelSpringBootRunner;
import org.apache.camel.test.spring.EnableRouteCoverage;
import org.apache.camel.test.spring.MockEndpointsAndSkip;
import org.apache.camel.test.spring.UseAdviceWith;
import org.assertj.core.api.Assertions;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.annotation.DirtiesContext;

import pl.muni.camel.sample.customer.infrastructure.rest.CreateCustomerResponse;

@UseAdviceWith
@MockEndpointsAndSkip("restlet*")
@EnableRouteCoverage
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@SpringBootTest
@ComponentScan("pl.muni.camel.sample.customer")
@RunWith(CamelSpringBootRunner.class)
public class SendCustomerDataToQueueIntegrationTest {

    @Produce
    private ProducerTemplate producerTemplate;

    @Autowired
    private CamelContext context;

    @EndpointInject(uri = "mock:error")
    private MockEndpoint errorEndpoint;

    @Before
    public void setUp() throws Exception {
        context.getRouteDefinition("processCreateCustomerRequest").adviceWith(context, new AdviceWithRouteBuilder() {
            @Override
            public void configure() {
                weaveByToUri("direct:processException")
                    .after()
                    .to("mock:error");
            }
        });

        context.start();
    }

    @After
    public void tearDown() throws Exception {
        context.stop();
    }

    @Test
    public void shouldReturnHttpStatus400ForInvalidJson() throws InterruptedException {
        // given
        final String customerDataString = "{\"firstName\": \"aaa\", \"lastname\": \"bbb\"}";

        //when
        producerTemplate.sendBody("direct:acceptRequest", customerDataString);

        //then
        errorEndpoint.expectedHeaderReceived(Exchange.HTTP_RESPONSE_CODE, 400);
        errorEndpoint.assertIsSatisfied();

        final List<Exchange> exchanges = errorEndpoint.getExchanges();
        Assertions.assertThat(exchanges).hasSize(1);

        final Exchange exchange = exchanges.get(0);
        final CreateCustomerResponse response = exchange.getIn().getBody(CreateCustomerResponse.class);
        Assertions.assertThat(response.isSuccess()).isFalse();
        Assertions.assertThat(response.getErrorMessage()).startsWith("UnrecognizedPropertyException: Unrecognized field \"lastname\"");
    }
}

不幸的是,Exchange.HTTP_RESPONSE_CODE标头在测试过程中以某种方式消失了,并且对errorEndpoint的声明失败。我使用CreateCustomerErrorResponseProcessor类中设置的调试器和断点运行了测试,并且标题仍然可用。

还有另一种设置测试并能够检索标头的方法,或者这可能是一个错误吗?

1 个答案:

答案 0 :(得分:0)

您在单元测试中编织的URI(“ direct:processException”)附加到错误的路由定义。 它应该是: context.getRouteDefinition(“ processCreateCustomerException”)。adviceWith(...) (而不是“ processCreateCustomerRequest”)

相关问题