如何解决Spring Boot WebMvcTest中的断言错误(状态码404)
你的问题主要出在@WebMvcTest的配置逻辑和测试断言的匹配性上,咱们一步步拆解解决:
1. 修复404请求找不到的核心问题
你在@WebMvcTest中添加了includeFilters = @ComponentScan.Filter(classes = EnableWebSecurity.class),这会覆盖@WebMvcTest默认的组件扫描规则——默认它会自动加载你指定的BookController,但添加includeFilters后,测试上下文只会保留匹配该过滤器的类,反而导致控制器没被正确加载,自然请求返回404。
另外你已经通过@AutoConfigureMockMvc(secure = false)禁用了安全验证,完全不需要再引入EnableWebSecurity配置。建议修改@WebMvcTest注解:
@AutoConfigureMockMvc(secure = false) @RunWith(SpringRunner.class) @WebMvcTest(controllers = {BookController.class})
2. 修正状态断言的错误匹配
你的addBookPost方法执行成功后返回redirect:bookList,对应HTTP 3xx重定向状态码,但测试里断言的是status().isOk()(期望200状态码),这即使请求到达控制器,断言也会失败。你需要把状态断言改成匹配重定向的规则:
.andExpect(status().is3xxRedirection()) // 可选:进一步验证重定向的目标路径 .andExpect(redirectedUrl("/book/bookList"))
3. 补充表单参数(可选但推荐)
控制器方法需要绑定@ModelAttribute("book") Book对象,测试时最好传递对应字段的表单参数,避免参数绑定失败影响测试完整性(虽然这不会导致404,但能让测试更贴近真实场景):
this.mockMvc.perform(post("/book/add") .accept(MediaType.TEXT_HTML) .contentType(MediaType.APPLICATION_FORM_URLENCODED) // 表单提交的正确Content-Type .param("title", "测试书籍") // 替换为你的Book类实际字段 .param("author", "测试作者"))
为什么@SpringBootTest能正常运行?
@SpringBootTest会加载整个应用上下文,包括所有配置类、控制器、服务等,不会出现组件遗漏的问题,但它的测试开销远大于@WebMvcTest。搞定@WebMvcTest的配置后,就能实现轻量高效的Web层测试。
内容的提问来源于stack exchange,提问作者valik

