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

Spring MVC Controller单元测试:java.util.Map数据绑定失败求助

Hey there! Let's dig into your Mockito/MockMVC testing issue with the DocTypeAdminCtrl.java controller. I’ve worked through similar Spring Boot testing headaches before, so let’s break this down step by step with actionable checks and examples tailored to your tech stack.

Common Troubleshooting Steps for MockMVC + Mockito Controller Tests

1. Nail Down Your Test Setup Annotations

First, confirm your test class uses the right annotation combo for Spring Boot 2.0.x + JUnit 5—this is a super common point of confusion:

  • Use @WebMvcTest(DocTypeAdminCtrl.class) to focus only on the controller layer (avoids loading your full application context)
  • Add @ExtendWith(MockitoExtension.class) to enable Mockito support in JUnit 5
  • Use @MockBean to inject mocked service dependencies directly into your controller (way cleaner than manual injection)

Example setup snippet:

@WebMvcTest(DocTypeAdminCtrl.class)
@ExtendWith(MockitoExtension.class)
class DocTypeAdminCtrlTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private DocTypeService docTypeService; // Replace with your actual service dependency

    // Test methods go here
}

2. Double-Check Request Mapping Alignment

If your tests are throwing 404s or unexpected status codes, verify these details:

  • The HTTP method (GET/POST/PUT/DELETE) in your mockMvc.perform() call matches exactly what’s defined in your controller (e.g., @GetMapping vs @PostMapping)
  • The request path matches the controller's mapping—watch for trailing slashes or missing path variables
  • For POST/PUT requests, ensure you’re passing data in the right format (use param() for form data, content() for JSON, matching what your controller expects)

Example GET request test for a Thymeleaf view:

@Test
void shouldReturnDocTypesList() throws Exception {
    // Arrange
    List<DocType> mockDocTypes = Arrays.asList(new DocType(1L, "Article"), new DocType(2L, "Book"));
    when(docTypeService.getAllDocTypes()).thenReturn(mockDocTypes);

    // Act & Assert
    mockMvc.perform(get("/admin/doc-types")
                    .contentType(MediaType.TEXT_HTML))
            .andExpect(status().isOk())
            .andExpect(model().attributeExists("docTypes"))
            .andExpect(view().name("admin/doc-types/list")); // Match your Thymeleaf template name
}

3. Validate Mocked Service Interactions

If your tests fail because service methods aren’t being called (or return wrong data):

  • Use verify(docTypeService).yourMethod(any()) to confirm the service was invoked with the correct arguments
  • Double-check method signatures—overloaded methods are a frequent culprit here
  • Avoid mixing @Mock and @Autowired unless you’re manually injecting mocks; @MockBean is the Spring-friendly approach

Example verification for a delete request:

@Test
void shouldDeleteDocType() throws Exception {
    // Act
    mockMvc.perform(delete("/admin/doc-types/{id}", 1L)
                    .contentType(MediaType.TEXT_HTML))
            .andExpect(status().is3xxRedirection())
            .andExpect(redirectedUrl("/admin/doc-types"));

    // Assert service was called once with the right ID
    verify(docTypeService, times(1)).deleteDocType(1L);
}

4. Handle Thymeleaf-Specific Edge Cases

Since you’re using Thymeleaf, keep these gotchas in mind:

  • For form POSTs, use param() to pass form fields (Thymeleaf forms typically use application/x-www-form-urlencoded instead of JSON)
  • Match the model attribute name exactly to what’s in your template (check th:object in your form markup)
  • If you’re validating HTML content, use andExpect(content().string(containsString("Expected Text"))) instead of strict full-content checks

Example form POST test:

@Test
void shouldCreateNewDocType() throws Exception {
    // Act
    mockMvc.perform(post("/admin/doc-types")
                    .param("name", "Report")
                    .contentType(MediaType.APPLICATION_FORM_URLENCODED))
            .andExpect(status().is3xxRedirection())
            .andExpect(redirectedUrl("/admin/doc-types"));

    // Capture and verify the saved DocType
    ArgumentCaptor<DocType> docTypeCaptor = ArgumentCaptor.forClass(DocType.class);
    verify(docTypeService).saveDocType(docTypeCaptor.capture());
    assertEquals("Report", docTypeCaptor.getValue().getName());
}

5. Debug Like a Pro

If you’re still stuck, these tricks will help you diagnose the issue fast:

  • Add .andDo(print()) to your MockMvc call to output full request/response details (this is a lifesaver for seeing exactly what’s being sent/received)
  • Temporarily switch to @SpringBootTest (with @AutoConfigureMockMvc) to run an integration test—this helps isolate if the problem is with your unit test setup or the controller itself
  • Check for global exception handlers or controller-level @ExceptionHandler methods that might be altering response status codes

If you can share specific error messages, snippets of your failing test code, or key parts of DocTypeAdminCtrl.java, I can give even more targeted advice to get your tests passing!

内容的提问来源于stack exchange,提问作者O. Bertuch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:48:46