You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 13:06:03