我正在尝试在下面的类中测试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
类中设置的调试器和断点运行了测试,并且标题仍然可用。
还有另一种设置测试并能够检索标头的方法,或者这可能是一个错误吗?
答案 0 :(得分:0)
您在单元测试中编织的URI(“ direct:processException”)附加到错误的路由定义。 它应该是: context.getRouteDefinition(“ processCreateCustomerException”)。adviceWith(...) (而不是“ processCreateCustomerRequest”)