java - 如何使用 MockMVC 对 Spring-Boot REST 端点进行单元测试,其中路径映射是环境变量?

标签 java spring-boot mocking mockmvc

我正在尝试为其配置严重依赖环境变量的服务编写单元测试。 单元测试对于服务层工作得很好,但我在尝试为直接从环境变量读取地址的端点设置 MockMVC 测试时遇到了问题。

我尝试直接在测试中设置变量,但我认为它需要应用程序上下文来填充 Controller 端值,并且我试图在简单的单元测试中避免这种情况。

使用:Java11、Mockito2、JUnit5、SpringBoot2.2.0.M6

Controller :

@RestController
public class OutgoingMessageAPI {

    private MessagingService service;

    public OutgoingMessageAPI(MessagingService service) {
        this.service = service;
    }

    @PostMapping("${MQTT_CLIENT_API_OUTGOING_MESSAGE}")
    public ResponseEntity postMessage(@RequestBody @Valid Message message) {
         service.handleOutgoingMessage(message);
    }

}

测试我手动生成 MockMVC BeforeEach 测试的位置:

@ExtendWith(MockitoExtension.class)
@DisplayName("Outgoing Message API Test")
class OutgoingMessageAPITest {

    private MockMvc mockMvc;

    @Mock
    private ObjectMapper objectMapper;

    @Mock
    private MessagingService messagingService;

    @InjectMocks
    private OutgoingMessageAPI outgoingMessageAPI;

    private Message validIncomingMessage;
    private String validIncomingMessageJSON;

    @BeforeEach
    void beforeEach() throws JsonProcessingException {
        mockMvc = MockMvcBuilders.standaloneSetup(outgoingMessageAPI).build();

        validIncomingMessage = new Message());
        validIncomingMessageJSON = new ObjectMapper().writeValueAsString(validIncomingMessage);
    }

    @Test
    @DisplayName("A valid message is posted")
    void postMessageValid() throws Exception {
        var endpoint = "/endpoint";
        System.setProperty("MQTT_CLIENT_API_OUTGOING_MESSAGE", endpoint);
        mockMvc.perform(post(endpoint)
                    .content(validIncomingMessageJSON)
                    .contentType("application/json"))
                .andExpect(status().isAccepted());
    }

收到的错误是:

    Invalid mapping on handler class [com.tlvlp.iot.server.mqtt.client.rpc.OutgoingMessageAPI]: public org.springframework.http.ResponseEntity com.tlvlp.iot.server.mqtt.client.rpc.OutgoingMessageAPI.postMessage(com.tlvlp.iot.server.mqtt.client.persistence.Message)
    Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'MQTT_CLIENT_API_OUTGOING_MESSAGE' in value "${MQTT_CLIENT_API_OUTGOING_MESSAGE}"

最佳答案

在独立设置中,不支持请求映射中嵌入的占位符值。所以你应该使用StandaloneMockMvcBuilder.addPlaceholderValue(...):

@BeforeEach
void beforeEach() throws JsonProcessingException {
    mockMvc = MockMvcBuilders.standaloneSetup(outgoingMessageAPI)
            .addPlaceholderValue("MQTT_CLIENT_API_OUTGOING_MESSAGE", "/endpoint")
            .build();
    ...
}

关于java - 如何使用 MockMVC 对 Spring-Boot REST 端点进行单元测试,其中路径映射是环境变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58117609/

相关文章:

gradle - POST 方法上的外部 tomcat 上的 Spring Boot REST 框架无法处理图像。返回 404 错误

java - GET , POST , PUT , DELETE keycloak 中基于类型的身份验证

ruby-on-rails - 为什么在测试时模拟数据?

java - (Java)获取google的前n个结果作为链接

java - 如何为 EJB 选择本地接口(interface)?

java - 小程序,JNLP。强制更新 jar 文件

java - 关于迭代图像中每个像素的简单问题

spring - 让 @SpringBootTest 在每次测试中使用新的应用程序

c# - 用参数模拟一个方法

python - 测试功能的正确方法