0

0

Spring MockMvc DELETE请求路径参数测试指南:处理空与无效ID

DDD

DDD

发布时间:2025-07-16 21:24:02

|

307人浏览过

|

来源于php中文网

原创

spring mockmvc delete请求路径参数测试指南:处理空与无效id

本教程详细讲解如何使用Spring MockMvc测试RESTful DELETE接口中的路径参数。重点阐述了MockMvc URL模板的正确用法,以及如何有效测试路径变量为零或为空字符串的场景。通过具体示例,我们将分析不同输入值如何影响请求路由和Spring的验证机制,帮助开发者避免常见的测试陷阱,确保API行为的健壮性与准确性。

在Spring Boot应用中,对RESTful API进行单元测试是确保其稳定性和正确性的关键环节。Spring MockMvc提供了一种强大的方式来模拟HTTP请求,从而在不启动完整服务器的情况下测试控制器逻辑。然而,在处理包含路径变量(Path Variable)的DELETE请求时,尤其是在测试非法或异常输入时,开发者可能会遇到一些常见的陷阱。本教程将深入探讨如何正确使用MockMvc测试DELETE请求,并着重解决路径参数为“空”或“零”的场景。

理解Spring MockMvc的URL模板

在MockMvc中构建请求时,正确使用URL模板至关重要。delete()方法允许我们定义一个带有占位符的URL,并随后提供实际的值来填充这些占位符。

考虑以下控制器方法:

@RestController
@RequestMapping("api/wallet")
@RequiredArgsConstructor
@Validated
public class WalletController {

    private final WalletService walletService;

    @DeleteMapping("/{id}")
    public ResponseEntity deleteWalletById(@Valid @Min(1) @PathVariable Long id) {
        walletService.deleteWalletById(id);
        HttpHeaders headers = new HttpHeaders();
        headers.add("message", "You have successfully completed the delete of a Wallet!");
        return new ResponseEntity<>(headers, HttpStatus.OK);
    }
}

这里,@DeleteMapping("/{id}")表示该端点期望一个名为id的路径变量,并且其类型为Long。@Min(1)注解进一步限制了id的值必须大于等于1。

在MockMvc测试中,正确的URL模板用法是:

mockMvc.perform(delete("/api/wallet/{id}", actualIdValue));

其中,{id}是占位符,actualIdValue是实际要插入到URL中的值。

常见错误示例与分析:

Peachly AI
Peachly AI

Peachly AI是一个一体化的AI广告解决方案,帮助企业创建、定位和优化他们的广告活动。

下载

许多开发者可能会尝试使用delete("/api/wallet/{}", id),并期望它能像字符串格式化一样工作。然而,这种用法是不正确的,尤其是在id为空字符串时。

如果id是一个空字符串"",那么delete("/api/wallet/{}", "")最终会生成/api/wallet/这个URL。这个URL与控制器中定义的@DeleteMapping("/{id}")不匹配,因为后者期望在/api/wallet/之后有一个非空的路径段。当Spring DispatcherServlet尝试将DELETE /api/wallet/请求映射到控制器时,它会发现没有匹配的DELETE方法处理这个确切的路径,从而可能抛出HttpRequestMethodNotSupportedException或404 Not Found。

场景一:测试ID为零的情况

当我们需要测试ID为零(0)的情况时,直接将零作为路径变量的值传递即可。

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;

// 假设 WalletController 和 WalletService 存在
// @WebMvcTest(WalletController.class) // 根据实际测试配置调整
class WalletControllerTest {

    @MockBean
    private WalletService walletService;

    @Autowired
    private MockMvc mockMvc;

    @Test
    void shouldReturnBadRequestWhenWalletIdIsZero() throws Exception {
        // given
        Long walletId = 0L; // 传入0L

        // when
        ResultActions result = mockMvc.perform(delete("/api/wallet/{id}", walletId)
                .contentType(MediaType.APPLICATION_JSON)); // DELETE请求通常不需要content

        // then
        result.andExpect(status().isBadRequest()) // 期望400 Bad Request
              // 验证@Min(1)的错误信息,具体路径可能因Spring Boot版本和错误处理机制而异
              .andExpect(jsonPath("$.errors[0].defaultMessage").value("must be greater than or equal to 1")); 
    }
}

解释: 在这种情况下,delete("/api/wallet/{id}", 0L)会生成请求URL /api/wallet/0。这个URL能够成功匹配到@DeleteMapping("/{id}")方法。然而,由于deleteWalletById方法中的@Min(1)注解,当id的值为0时,Spring的验证机制会捕获到这个不合法的输入,并抛出MethodArgumentNotValidException,最终导致HTTP状态码为400 Bad Request。这是符合预期的行为。

场景二:测试ID为空字符串的情况

测试ID为空字符串("")的场景需要特别注意,因为这涉及到URL路径匹配的底层机制。

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

// @WebMvcTest(WalletController.class) // 根据实际测试配置调整
class WalletControllerEmptyIdTest {

    @MockBean
    private WalletService walletService;

    @Autowired
    private MockMvc mockMvc;

    @Test
    void shouldReturnNotFoundOrBadRequestWhenWalletIdIsEmptyString() throws Exception {
        // given
        String walletId = ""; // 尝试传入空字符串

        // when
        ResultActions result = mockMvc.perform(delete("/api/wallet/{id}", walletId)
                .contentType(MediaType.APPLICATION_JSON));

        // then
        // 预期行为可能因Spring版本和配置而异:
        // 1. 如果Spring无法将空字符串解析为Long,通常是400 Bad Request (Type Mismatch)
        // 2. 如果路径最终解析为 /api/wallet/ 且没有匹配的DELETE方法,可能是404 Not Found 或 405 Method Not Allowed
        // 原始问题中出现500,通常是更深层次的DispatcherServlet处理异常
        result.andExpect(status().isBadRequest()); // 假设Type Mismatch或类似的客户端错误优先发生
    }
}

解释: 当delete("/api/wallet/{id}", "")被执行时,MockMvc会尝试将空字符串""插入到{id}占位符中。这最终会形成请求路径/api/wallet/。

  1. 路径不匹配: DELETE /api/wallet/与@DeleteMapping("/{id}")(期望/api/wallet/{something})是不匹配的。因此,Spring的请求映射器将找不到一个合适的处理器
  2. 类型转换失败: 即使某种情况下路径能够匹配(例如,如果{id}可以接受空路径段,这在默认情况下不是),Long id参数也无法将空字符串解析为有效的Long类型。这通常会导致TypeMismatchException,从而触发400 Bad Request响应。
  3. HttpRequestMethodNotSupportedException / 405 Method Not Allowed: 如果/api/wallet/路径上存在其他HTTP方法的映射(例如GET /api/wallet/),但没有DELETE方法的映射,那么尝试DELETE /api/wallet/可能会导致405 Method Not Allowed。原始问题中出现的500 Internal Server Error伴随着HttpRequestMethodNotSupportedException,这表明DispatcherServlet在尝试匹配请求时遇到了问题,并且没有找到任何支持DELETE方法的处理程序,最终以500状态码返回。

重要提示: 如果你的API设计不允许id为空,那么测试其导致400 Bad Request或404 Not Found是合理的。关键在于理解delete("/api/wallet/{id}", "")不等同于请求一个“空ID”的路径变量,而是请求了一个完全不同的URL路径:/api/wallet/。如果你确实需要处理/api/wallet/这个端点,你可能需要单独为其定义一个控制器方法,例如:

// 如果你需要处理 /api/wallet/ 的DELETE请求,但它不带ID
@DeleteMapping("/") // 或者 @DeleteMapping
public ResponseEntity deleteAllWallets() {
    // ... 处理逻辑
    return ResponseEntity.status(HttpStatus.METHOD_NOT_ALLOWED).body("Deleting all wallets without specific ID is not allowed.");
}

但通常情况下,DELETE /api/wallet/并非删除单个资源的常见RESTful模式。

总结与最佳实践

  • 正确使用URL模板: 始终使用delete("/path/{id}", value)的格式,确保占位符被正确填充。避免使用{}而不提供参数,或尝试将空字符串直接插入到占位符中,除非你明确知道这会生成你想要测试的URL。
  • 区分路径匹配与参数验证: Spring首先尝试将请求路径匹配到控制器方法。如果匹配成功,才会进行参数类型转换和验证。@PathVariable要求路径段非空。
  • 预期行为:
    • 无效数值(如0但@Min(1)): 通常导致400 Bad Request(参数验证失败)。
    • 无法解析的类型(如空字符串给Long):

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

98

2025.08.06

spring boot框架优点
spring boot框架优点

spring boot框架的优点有简化配置、快速开发、内嵌服务器、微服务支持、自动化测试和生态系统支持。本专题为大家提供spring boot相关的文章、下载、课程内容,供大家免费下载体验。

135

2023.09.05

spring框架有哪些
spring框架有哪些

spring框架有Spring Core、Spring MVC、Spring Data、Spring Security、Spring AOP和Spring Boot。详细介绍:1、Spring Core,通过将对象的创建和依赖关系的管理交给容器来实现,从而降低了组件之间的耦合度;2、Spring MVC,提供基于模型-视图-控制器的架构,用于开发灵活和可扩展的Web应用程序等。

384

2023.10.12

Java Spring Boot开发
Java Spring Boot开发

本专题围绕 Java 主流开发框架 Spring Boot 展开,系统讲解依赖注入、配置管理、数据访问、RESTful API、微服务架构与安全认证等核心知识,并通过电商平台、博客系统与企业管理系统等项目实战,帮助学员掌握使用 Spring Boot 快速开发高效、稳定的企业级应用。

64

2025.08.19

Java Spring Boot 4更新教程_Java Spring Boot 4有哪些新特性
Java Spring Boot 4更新教程_Java Spring Boot 4有哪些新特性

Spring Boot 是一个基于 Spring 框架的 Java 开发框架,它通过 约定优于配置的原则,大幅简化了 Spring 应用的初始搭建、配置和开发过程,让开发者可以快速构建独立的、生产级别的 Spring 应用,无需繁琐的样板配置,通常集成嵌入式服务器(如 Tomcat),提供“开箱即用”的体验,是构建微服务和 Web 应用的流行工具。

12

2025.12.22

Java Spring Boot 微服务实战
Java Spring Boot 微服务实战

本专题深入讲解 Java Spring Boot 在微服务架构中的应用,内容涵盖服务注册与发现、REST API开发、配置中心、负载均衡、熔断与限流、日志与监控。通过实际项目案例(如电商订单系统),帮助开发者掌握 从单体应用迁移到高可用微服务系统的完整流程与实战能力。

102

2025.12.24

PHP API接口开发与RESTful实践
PHP API接口开发与RESTful实践

本专题聚焦 PHP在API接口开发中的应用,系统讲解 RESTful 架构设计原则、路由处理、请求参数解析、JSON数据返回、身份验证(Token/JWT)、跨域处理以及接口调试与异常处理。通过实战案例(如用户管理系统、商品信息接口服务),帮助开发者掌握 PHP构建高效、可维护的RESTful API服务能力。

145

2025.11.26

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

184

2023.10.18

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

74

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Django 教程
Django 教程

共28课时 | 2.7万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.0万人学习

Sass 教程
Sass 教程

共14课时 | 0.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号