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

如何使用MockMvc测试带有查询参数的Spring Controller?

Testing Your AppointmentController with MockMvc (Query Parameters Included)

No worries, let's break down exactly how to test your AppointmentController using MockMvc, including how to pass query parameters correctly—even for those LocalDate parameters that might seem tricky at first.

First, Set Up Your Test Class

Start by creating a test class focused on controller testing. We'll use @WebMvcTest to isolate the controller, inject MockMvc to simulate HTTP requests, and mock your AppointmentService so we don't depend on real database calls:

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.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@WebMvcTest(AppointmentController.class)
class AppointmentControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private AppointmentService appointmentService; // Replace with your actual service type
}

Test 1: /getAppointmentById (Single Query Parameter)

For this endpoint, you just need to pass the id query parameter using the .param() method in your MockMvc request. We'll test both a successful case and an error case:

@Test
void getAppointmentById_Success() throws Exception {
    // Mock the service response
    Long appointmentId = 1L;
    AppointmentDto mockDto = new AppointmentDto();
    mockDto.setId(appointmentId);
    // Add other fields as needed for your DTO

    when(appointmentService.getAppointmentById(appointmentId)).thenReturn(mockDto);

    // Perform the GET request with query parameter
    mockMvc.perform(get("/getAppointmentById")
                    .param("id", appointmentId.toString()) // Pass the Long as a string
                    .contentType(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.id").value(appointmentId));
    // Add more jsonPath assertions for other DTO fields
}

@Test
void getAppointmentById_InternalServerError() throws Exception {
    Long appointmentId = 999L;

    // Mock the service to throw an exception
    when(appointmentService.getAppointmentById(appointmentId)).thenThrow(new RuntimeException("Not found"));

    mockMvc.perform(get("/getAppointmentById")
                    .param("id", appointmentId.toString()))
            .andExpect(status().isInternalServerError())
            .andExpect(content().string("")); // Since you return null body on error
}

Test 2: /getAppointmentToPatient (Multiple Parameters Including LocalDate)

This endpoint has three query parameters: patientId, startDate, and endDate. Thanks to your @DateTimeFormat(pattern = "yyyy-MM-dd") annotation, you can just pass date strings in that format—MockMvc and Spring will automatically convert them to LocalDate objects for you:

@Test
void getAppointmentToPatient_Success() throws Exception {
    // Mock data
    Long patientId = 101L;
    LocalDate startDate = LocalDate.of(2024, 1, 1);
    LocalDate endDate = LocalDate.of(2024, 1, 31);
    List<Appointment> mockAppointments = List.of(new Appointment()); // Populate with test data

    when(appointmentService.getAppointmentToPatient(patientId, startDate, endDate)).thenReturn(mockAppointments);

    // Perform request with all three query parameters
    mockMvc.perform(get("/getAppointmentToPatient")
                    .param("patientId", patientId.toString())
                    .param("startDate", "2024-01-01") // Match your @DateTimeFormat pattern
                    .param("endDate", "2024-01-31")
                    .contentType(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$").isArray())
            .andExpect(jsonPath("$.length()").value(mockAppointments.size()));
}

@Test
void getAppointmentToPatient_InternalServerError() throws Exception {
    Long patientId = 999L;

    when(appointmentService.getAppointmentToPatient(patientId, LocalDate.of(2024,1,1), LocalDate.of(2024,1,31)))
            .thenThrow(new RuntimeException("Error fetching appointments"));

    mockMvc.perform(get("/getAppointmentToPatient")
                    .param("patientId", patientId.toString())
                    .param("startDate", "2024-01-01")
                    .param("endDate", "2024-01-31"))
            .andExpect(status().isInternalServerError())
            .andExpect(content().string(""));
}

Key Notes

  • Passing Query Params: Use .param("paramName", "paramValue") for each query parameter. For numeric types like Long, just convert to a string—Spring will handle the conversion.
  • LocalDate Handling: Your @DateTimeFormat annotation tells Spring how to parse the string parameter into a LocalDate, so as long as you pass the date in yyyy-MM-dd format, it will work seamlessly.
  • Mocking the Service: Using @MockBean ensures we don't call real service logic—we control exactly what the service returns, so we can test all edge cases (success, errors) without external dependencies.

内容的提问来源于stack exchange,提问作者Suraj Rathod

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 17:57:28