You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring MockMvc调用中添加ModelAttribute以测试控制器成功路径?

解决MockMvc测试中添加ModelAttribute触发成功路径的问题

我完全懂你的困扰——要测试这个遵循Post/Redirect/Get模式的成功路径,核心就是要在MockMvc的GET请求里模拟出ADDED_OBJECT这个Model属性的存在。下面给你两种实用的解决方案:


方案1:直接为GET请求添加请求属性

如果只是单独测试/added这个端点的成功逻辑,可以直接在MockMvc的请求构建中添加请求属性,Spring MVC的Model会自动识别并包含这些属性:

@Test
public void added_WithAddedObjectAttribute_ReturnsSuccessPage() throws Exception {
    // 这里可以是任意你需要的对象,比如业务实体类实例或者简单Object
    Object addedObject = new Object();

    mockMvc.perform(get("/added")
            .requestAttr("ADDED_OBJECT", addedObject)) // 直接往请求里添加属性
        .andExpect(status().isOk())
        .andExpect(content().string(not(containsString("400"))))
        .andExpect(view().name("added")); // 可以额外验证视图名称,让测试更严谨
}

因为model.containsAttribute()会自动检查请求属性、会话属性以及Flash属性,所以用requestAttr()就能让控制器检测到ADDED_OBJECT的存在,触发成功路径。


方案2:模拟完整的Post/Redirect/Get流程

如果想更贴近真实业务场景(模拟POST提交成功后重定向到/added的完整流程),可以先发送POST请求并添加Flash属性,再跟随重定向到目标端点:

假设你的POST提交控制器大概是这样的(示例):

@PostMapping("/submit")
public String submitForm(RedirectAttributes redirectAttributes) {
    // 处理业务逻辑...
    redirectAttributes.addFlashAttribute("ADDED_OBJECT", new Object());
    return "redirect:/added";
}

对应的测试代码可以这么写:

@Test
public void submitForm_RedirectsToAdded_WithFlashAttribute() throws Exception {
    // 先模拟POST提交,验证重定向
    mockMvc.perform(post("/submit")
            // 可以按需添加POST请求参数,比如.param("name", "test")
        )
        .andExpect(status().is3xxRedirection())
        .andExpect(redirectedUrl("/added"));

    // 模拟重定向后的GET请求,携带Flash属性
    mockMvc.perform(get("/added")
            .flashAttr("ADDED_OBJECT", new Object()))
        .andExpect(status().isOk())
        .andExpect(content().string(not(containsString("400"))));
}

或者更简洁的方式,先获取重定向地址再发起请求:

@Test
public void submitForm_CompletePRGFlow() throws Exception {
    MvcResult result = mockMvc.perform(post("/submit"))
        .andExpect(status().is3xxRedirection())
        .andReturn();

    String redirectedUrl = result.getResponse().getRedirectedUrl();

    mockMvc.perform(get(redirectedUrl)
            .flashAttr("ADDED_OBJECT", new Object()))
        .andExpect(status().isOk())
        .andExpect(view().name("added"));
}

另外提个小建议:如果控制器里的ADDED_OBJECT是常量定义的,测试里直接引用这个常量,别硬编码字符串,比如:

// 假设控制器中定义了常量
public static final String ADDED_OBJECT = "addedObject";

// 测试中直接引用
.requestAttr(YourController.ADDED_OBJECT, addedObject)

这样能避免属性名称不一致导致的测试失败,让代码更健壮。

内容的提问来源于stack exchange,提问作者Patrick Adler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:28:22