SpringBoot集成Camel REST POST接口JUnit测试断言失败求助
正确实现方案
方案1:核心路由逻辑单元测试
该方案直接测试路由业务逻辑,Mock掉第三方调用,不需要启动完整Web容器:
import org.apache.camel.CamelContext; import org.apache.camel.ProducerTemplate; import org.apache.camel.builder.AdviceWith; import org.apache.camel.component.mock.MockEndpoint; import org.apache.camel.test.spring.junit5.CamelSpringBootTest; import org.apache.camel.test.spring.junit5.UseAdviceWith; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import static org.junit.jupiter.api.Assertions.assertEquals; @SpringBootTest @CamelSpringBootTest @UseAdviceWith // 开启AdviceWith支持,手动控制上下文启动 public class OMSUtilsApplicationTest { @Autowired private CamelContext camelContext; @Autowired private ProducerTemplate producerTemplate; private final ObjectMapper mapper = new ObjectMapper(); @Test public void testKiboPostAPICallRoute() throws Exception { // 1. 修改路由,Mock第三方Kibo API调用节点 AdviceWith.adviceWith(camelContext, "KiboPostAPICallRoute", r -> { // 替换调用Kibo接口的toD节点,返回Mock响应 r.weaveById("CallKiboAPIforPostCall").replace().to("mock:kiboApiResponse"); }); // 2. 启动Camel上下文 camelContext.start(); // 3. 构造Mock返回值 String mockKiboResponse = "{\"status\": 400,\"errorMessage\": \"Bad Request\",\"additionalInfo\": \"Order 608 cannot fully appease the requested 0.2 amount. Total amount left to refund is 0.17\",\"errorCode\": 5003,\"timestamp\": \"2021-10-25T08:35:28.677857Z\"}"; MockEndpoint mockKibo = camelContext.getEndpoint("mock:kiboApiResponse", MockEndpoint.class); mockKibo.whenAnyExchangeReceived(exchange -> { exchange.getMessage().setBody(mockKiboResponse); }); // 4. 构造请求参数,调用路由入口 String request = "{\"kiboAPIPath\": \"/api/v2/orderAppeasement/\",\"queryParams\": [{\"key\": \"orderID\",\"value\": \"608\"}],\"body\": {\"creditPayee\": \"MANUFACTURER\",\"creditAmount\": 0.2,\"creditDescription\": \"CREDIT SETTLEMENT\",\"userID\": \"8910928\"}}"; String actualResponse = producerTemplate.requestBody("direct:kibo-post-api-call", request, String.class); // 5. 反序列化JSON,忽略timestamp比对业务字段 JsonNode actualNode = mapper.readTree(actualResponse); JsonNode expectedNode = mapper.readTree(mockKiboResponse); assertEquals(expectedNode.get("status").asInt(), actualNode.get("status").asInt()); assertEquals(expectedNode.get("errorMessage").asText(), actualNode.get("errorMessage").asText()); assertEquals(expectedNode.get("additionalInfo").asText(), actualNode.get("additionalInfo").asText()); assertEquals(expectedNode.get("errorCode").asInt(), actualNode.get("errorCode").asInt()); // 校验Mock节点被调用一次 mockKibo.assertIsSatisfied(); } }
方案2:完整REST API集成测试
如果需要测试整个REST接口的调用链路(包含Servlet层),可以使用TestRestTemplate发起真实HTTP请求:
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.*; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import static org.junit.jupiter.api.Assertions.assertEquals; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class CamelRestApiIntegrationTest { @Autowired private TestRestTemplate restTemplate; private final ObjectMapper mapper = new ObjectMapper(); @Test public void testRestApi() throws Exception { // 构造请求 String requestBody = "{\"kiboAPIPath\": \"/api/v2/orderAppeasement/\",\"queryParams\": [{\"key\": \"orderID\",\"value\": \"608\"}],\"body\": {\"creditPayee\": \"MANUFACTURER\",\"creditAmount\": 0.2,\"creditDescription\": \"CREDIT SETTLEMENT\",\"userID\": \"8910928\"}}"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity<String> request = new HttpEntity<>(requestBody, headers); // 发起POST请求 ResponseEntity<String> response = restTemplate.postForEntity("/rest/v1/kibo-api-post-call", request, String.class); assertEquals(HttpStatus.OK, response.getStatusCode()); // 校验响应业务字段 JsonNode actualNode = mapper.readTree(response.getBody()); assertEquals(400, actualNode.get("status").asInt()); assertEquals("Bad Request", actualNode.get("errorMessage").asText()); assertEquals("Order 608 cannot fully appease the requested 0.2 amount. Total amount left to refund is 0.17", actualNode.get("additionalInfo").asText()); assertEquals(5003, actualNode.get("errorCode").asInt()); } }
内容的提问来源于stack exchange,提问作者Kiran
相关产品推荐
相关产品推荐

