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

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@Validatedpublic 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中的值。

常见错误示例与分析:

许多开发者可能会尝试使用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/。

路径不匹配: DELETE /api/wallet/与@DeleteMapping(“/{id}”)(期望/api/wallet/{something})是不匹配的。因此,Spring的请求映射器将找不到一个合适的处理器类型转换失败: 即使某种情况下路径能够匹配(例如,如果{id}可以接受空路径段,这在默认情况下不是),Long id参数也无法将空字符串解析为有效的Long类型。这通常会导致TypeMismatchException,从而触发400 Bad Request响应。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("/") // 或者 @DeleteMappingpublic 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 MockMvc DELETE请求路径参数测试指南:处理空与无效ID的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/131205.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
4月份我国集成电路、光电子器件制造增加值分别增长21.3%和19%
上一篇 2025年11月28日 16:27:48
百度个性化推荐怎么管理_百度管理个性化推荐设置方法
下一篇 2025年11月28日 16:30:51

相关推荐

  • 减少PHP与MySQL数据库通信的延迟

    减少php与mysql数据库通信的延迟可以通过以下策略:1. 优化数据库查询,使用索引提升查询速度;2. 减少数据库连接次数,使用连接池管理连接;3. 查询优化,使用explain分析查询计划;4. 使用缓存,如redis,减少数据库查询次数。这些方法能显著提升应用性能,但需权衡利弊,确保系统稳定性…

    2026年9月24日
    000
  • 温度墙和功耗墙是如何限制CPU性能发挥的?

    温度墙和功耗墙共同限制CPU性能。温度墙指CPU最高安全温度,超温会降频防损;功耗墙则设定了最大电能消耗,超限即限频。两者联动作用,高负载下先触功耗墙,后因积热触发温度墙,导致性能下降。优化需同步提升散热与供电。 温度墙和功耗墙是现代CPU在运行过程中为保障稳定性、安全性和能效而设置的两种关键限制机…

    2026年9月24日
    300
  • 讯维解决KVM鼠标不同步

    讯维解决KVM鼠标不同步讯维解决KVM鼠标不同步讯维解决KVM鼠标不同步讯维解决KVM鼠标不同步

    使用网络kvm时,常遇到本地鼠标与远程界面光标位置不一致的问题,即鼠标不同步现象,严重影响操作流畅性。可通过优化鼠标同步设置、更新驱动程序或选用兼容性更强的设备来有效改善。 1、配置运行Windows 2000操作系统的服务器环境 2、调整鼠标相关参数 3、点击开始菜单,进入控制面板,选择“鼠标”进…

    2026年9月24日 用户投稿
    900
  • 如何分析Linux进程内存 pmap内存映射检查方法

    如何分析Linux进程内存 pmap内存映射检查方法如何分析Linux进程内存 pmap内存映射检查方法如何分析Linux进程内存 pmap内存映射检查方法如何分析Linux进程内存 pmap内存映射检查方法

    要分析linux进程的内存,特别是利用pmap工具,核心操作是获取目标进程pid后执行pmap -x 。1. 获取pid可通过ps aux | grep your_process_name;2. 执行pmap -x 命令查看扩展格式信息,包括address、kbytes、rss、dirty、mode…

    2026年9月24日 用户投稿
    200
  • 笔记本百度影音播高清卡顿解决

    笔记本百度影音播高清卡顿解决笔记本百度影音播高清卡顿解决笔记本百度影音播高清卡顿解决笔记本百度影音播高清卡顿解决

    今天下载了高清版的《神偷奶爸2》,结果在电脑上播放时出现明显卡顿,反而用手机播放却非常流畅。经过一番排查,最终找到了问题所在,并顺利解决。现在将解决方法整理出来,希望能帮到同样被高清视频卡顿困扰的朋友。 1、 很多笔记本电脑都配备了双显卡系统,平时默认使用的是集成显卡,虽然省电但性能有限。为了提升百…

    2026年9月24日 用户投稿
    000
  • PHP实时输出如何防止XSS攻击_PHP实时输出安全防范XSS攻击

    防止XSS攻击需坚持三重防护:首先对用户输入进行严格验证与白名单过滤,使用filter_var等函数校验数据格式;其次根据输出上下文进行恰当转义——HTML正文和属性用htmlspecialchars(),JavaScript变量用json_encode(),URL参数用urlencode();最后…

    2026年9月24日
    100
  • ITX主板在极限紧凑空间下,其扩展性与散热兼容性面临着哪些具体挑战?

    ITX主板因尺寸小导致扩展性受限,仅支持单显卡、双内存插槽、有限M.2与SATA接口,I/O端口缩减;散热受紧凑布局影响,VRM易积热,风道差,散热器高度受限,M.2易过热;装机需精确匹配部件尺寸,电源限SFX,走线困难,兼容性要求高,小体积代价显著。 ITX主板在追求极致小巧的机身时,扩展性和散热…

    2026年9月24日
    100
  • Java中接口常量和类常量的使用区别

    接口常量默认public static final,用于行为契约但易导致职责模糊;类常量可用不同访问修饰符,更适合封装和维护。现代Java推荐使用专用常量类、枚举、私有静态常量或配置文件管理常量,以提升代码清晰度与可维护性。 Java中接口常量和类常量,核心区别在于它们的定义位置和隐式属性。接口常量…

    2026年9月24日
    000
  • AI PC的概念是炒作还是未来趋势?

    AI PC正通过专用芯片、本地化智能和新交互模式重塑个人电脑。专用NPU算力突破50TOPS,使设备可高效运行图像识别、语音分析等AI任务,实现快速安全的本地处理;高通在骁龙X Elite上运行130亿参数大模型,微软Windows 11原生支持本地AI,让文档润色、图像修复等操作可在无网环境下完成…

    2026年9月24日
    200
  • 处理PHP多线程的定时任务并行_优化php多线程怎么实现的定时任务执行

    PHP可通过多进程、消息队列等方式实现定时任务并行处理。1. 使用pthreads扩展(需ZTS支持)可在CLI环境实现多线程,但部署复杂;2. 利用pcntl_fork创建子进程是推荐方案,通过fork多个进程并行执行任务,适合CLI模式;3. 通过crontab同时触发多个独立脚本或使用exec…

    2026年9月24日
    200
  • 怎样处理C++中的野指针问题 空指针检测与防御性编程

    怎样处理C++中的野指针问题 空指针检测与防御性编程怎样处理C++中的野指针问题 空指针检测与防御性编程怎样处理C++中的野指针问题 空指针检测与防御性编程怎样处理C++中的野指针问题 空指针检测与防御性编程

    野指针难以发现是因为其指向已失效或非法内存,解引用会导致未定义行为。1. 初始化是关键防线,声明指针时必须赋初值或设为nullptr;2. 使用智能指针std::unique_ptr和std::shared_ptr可自动管理内存生命周期,避免手动delete遗漏;3. 防御性编程要求每次使用指针前进…

    2026年9月24日 用户投稿
    200
  • VSCode如何实现移动端调试 VSCode连接Android/iOS设备的技巧

    vscode本身不支持移动端调试,但可通过插件和工具间接实现。1. 调试android应用时,需开启设备开发者模式和usb调试,连接电脑后通过chrome浏览器访问chrome://inspect/#devices,使用chrome devtools调试webview;可配合vscode的debug…

    2026年9月24日
    000
  • php数据如何实现文件断点续传_php数据大文件上传解决方案

    断点续传通过文件分片、唯一hash标识、服务端记录上传状态实现,前端切片上传并查询已传分片,PHP后端存储分片并在完成后合并,同时提供状态接口支持续传,需注意hash一致性与临时文件清理。 大文件上传在Web开发中是个常见需求,尤其是涉及视频、备份文件或资源包时。PHP本身对文件上传有一定限制,但通…

    2026年9月24日
    000
  • VS Code工作台UI:自定义CSS与视图容器配置

    可通过扩展和配置自定义VS Code UI:1. 使用Custom CSS and JS Loader注入CSS修改外观,但有风险;2. 推荐创建Color Theme扩展,通过JSON定义主题颜色;3. 利用viewsContainers在活动栏添加自定义容器;4. 用户可设置view.locat…

    2026年9月24日
    000
  • 主板的供电相数是否真的“越多越好”,还是已成为营销的噱头?

    供电相数并非越多越好,实际需结合CPU和使用场景。多相供电可分担电流、提升稳定性,但高相数常被倍相技术夸大,用料与散热不足则性能受限。普通用户6+2相已足够,仅高端超频需求者需12相以上。判断供电实力应关注Dr. MOS、PWM芯片、电感电容品质及散热设计,而非单纯相数。 主板供电相数是不是越多越好…

    2026年9月24日
    100
  • PHP 中如何将 JSON 数组值声明为变量

    本文介绍了如何在 PHP 中从数据库获取数据并将其编码为 JSON 格式,然后通过 AJAX 请求传递到另一个页面。重点讲解了如何在接收页面解析 JSON 数据,并将 JSON 数组中的特定值提取并赋值给变量,以便在后续的 PHP 函数中使用。 从数据库获取数据并编码为 JSON 首先,我们需要从数…

    2026年9月24日
    000
  • 行业首款风水双冷手机 红魔11 Pro系列真机开箱:酷炫水冷环、唯一纯平后盖

    行业首款风水双冷手机 红魔11 Pro系列真机开箱:酷炫水冷环、唯一纯平后盖行业首款风水双冷手机 红魔11 Pro系列真机开箱:酷炫水冷环、唯一纯平后盖行业首款风水双冷手机 红魔11 Pro系列真机开箱:酷炫水冷环、唯一纯平后盖行业首款风水双冷手机 红魔11 Pro系列真机开箱:酷炫水冷环、唯一纯平后盖

    10月13日,红魔正式宣布其新款旗舰手机——红魔11 pro系列将于10月17日发布,这款机型将成为全球首款融合风冷与水冷双重散热技术的智能手机。 今天,红魔游戏手机官方首次展示了红魔11 Pro系列的真机开箱画面。新机共推出四种配色方案:氘锋透明暗夜、氘锋透明银翼、暗夜骑士以及银翼战神,满足不同用…

    2026年9月24日 用户投稿
    200
  • Laravel 表单多动作处理:区分同一路由下的提交操作

    本教程将详细介绍如何在 laravel 应用中,通过一个 html 表单的多个提交按钮触发不同的后端操作,而无需为每个操作创建单独的表单或路由。核心方法是为提交按钮添加 `name` 和 `value` 属性,然后在控制器中根据这些属性的值来判断执行哪种业务逻辑,从而实现如更新用户角色和删除用户等多…

    2026年9月24日
    000
  • Spring Boot 测试中 403 错误排查与安全配置优化

    本文旨在解决 Spring Boot 控制器层测试中常见的 403 Forbidden 错误,特别是当安全配置限制了访问权限时。文章将深入分析 WebSecurityConfig 和 @WithMockUser 的使用,提供两种主要解决方案:通过临时放松安全限制进行测试,以及确保角色/权限配置的正确…

    2026年9月24日
    100
  • 微星、华硕、华擎集体官方确认:B850主板可以升级Zen6

    10月13日最新消息,amd zen6架构的锐龙处理器将继续沿用am5插槽,全面兼容现有的600和800系列主板,这一消息已基本尘埃落定。近期,多家主板厂商首次通过官方渠道确认了该信息。 首先是微星,在社交平台与用户的互动中明确回应:800系列主板已为未来CPU做好准备(future CPU rea…

    2026年9月24日
    000

发表回复

登录后才能评论
关注微信