
在开发spring restful api时,对控制器层进行单元测试是至关重要的环节。mockmvc作为spring test模块的核心工具,提供了强大的能力来模拟http请求并验证控制器行为。然而,在测试涉及路径变量的delete请求时,开发者可能会遇到一些常见的陷阱,尤其是在处理“空”或“零值”id的场景。
Spring MockMvc在构建请求URI时,支持类似于String.format()的URL模板语法。这意味着,当控制器定义了一个带有路径变量的端点,例如@DeleteMapping("/{id}")时,MockMvc应该使用占位符来构建请求。
假设我们有一个WalletController,其删除方法如下:
@RestController
@RequestMapping("api/wallet")
@RequiredArgsConstructor
@Validated
public class WalletController {
private final WalletService walletService;
@DeleteMapping("/{id}")
public ResponseEntity<WalletDTO> 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);
}
}注意@PathVariable Long id上的@Min(1)注解,它要求id的值必须大于或等于1。
正确使用URL模板
当我们需要测试一个特定的ID,例如123L时,正确的MockMvc调用方式是:
mockMvc.perform(delete("/api/wallet/{id}", 123L));这里的{id}是一个占位符,123L是实际传入的值。MockMvc会将其解析为/api/wallet/123。
针对上述控制器中的@Min(1)验证,如果我们尝试传入id = 0L,请求应该被控制器捕获并在验证阶段失败,返回400 Bad Request。
以下是测试零值ID的示例:
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 static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.mockito.Mockito.verifyNoInteractions;
@WebMvcTest(WalletController.class) // 指定测试的控制器
class WalletControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private WalletService walletService; // 模拟服务层
@Test
void shouldReturnBadRequestWhenWalletIdIsZeroDueToValidation() throws Exception {
// Given
Long id = 0L; // ID为0,违反@Min(1)约束
// When
mockMvc.perform(delete("/api/wallet/{id}", id)
.contentType(MediaType.APPLICATION_JSON))
// Then
.andExpect(status().isBadRequest()); // 期望400 Bad Request
// 验证服务层方法未被调用,因为请求在控制器验证阶段就被拒绝了
verifyNoInteractions(walletService);
}
}在这个测试中,delete("/api/wallet/{id}", id)会生成/api/wallet/0这个URI。由于0不满足@Min(1)的条件,Spring的验证机制会拦截请求,并返回400 Bad Request,服务层方法不会被执行。
这是最容易引起混淆和错误的地方。当尝试用空字符串""作为路径变量的值时,例如delete("/api/wallet/{}", ""),MockMvc最终生成的URI将是/api/wallet/。
为什么这会导致问题?
测试“空”ID的示例:
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 static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.mockito.Mockito.verifyNoInteractions;
@WebMvcTest(WalletController.class)
class WalletControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private WalletService walletService;
@Test
void shouldReturnClientErrorWhenWalletIdIsEmptyString() throws Exception {
// Given
String idString = ""; // 空字符串作为ID,导致URI变为 /api/wallet/
// When
mockMvc.perform(delete("/api/wallet/{id}", idString) // 生成 /api/wallet/
.contentType(MediaType.APPLICATION_JSON))
// Then
// 期望4xx客户端错误,因为 /api/wallet/ 不匹配 /{id} 模式
// 具体是404 Not Found 或 405 Method Not Allowed 取决于其他映射
.andExpect(status().is4xxClientError());
// 验证服务层方法未被调用,因为请求根本没有匹配到带有ID的DELETE端点
verifyNoInteractions(walletService);
}
}在这个测试中,我们期望得到一个4xx客户端错误。404 Not Found是最常见的响应,因为它表示没有找到匹配/api/wallet/且支持DELETE方法的处理器。405 Method Not Allowed也可能发生,如果/api/wallet/路径存在但只支持其他HTTP方法。
通过本文的讲解和示例,我们深入理解了在Spring MockMvc中测试DELETE请求时,如何正确处理路径变量。关键在于理解MockMvc的URL模板机制,并区分零值ID与空字符串ID在请求路径解析上的不同。对于零值ID,如果存在验证规则,预期会得到400 Bad Request;而对于空字符串ID,由于URI不匹配,通常会得到404 Not Found或405 Method Not Allowed。掌握这些细节,将有助于编写更健壮、更准确的控制器测试。
以上就是Spring MockMvc DELETE请求路径变量测试指南的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号