[Spring] 테스트코드 MockMvc vs MockServerHttpRequest

 

MockMvc 코드

@AutoConfigureMockMvc
class CustomControllerTest {
	@Autowired
    private lateinit var mockMvc: MockMvc
}

@Test
fun `test should pass() {
	mockMvc.perform(
    	get("/url/etc")
        .accept(MediaType.APPLICATION_JSON)
        .param("", "")
    )
    .andExpect(status().isOk)
}

 

MockServerHttpRequest 코드

class CustomControllerTest {
	priavet lateinit var mockServerHttpRequest: MockServerHttpRequest
    
    @BeforeEach
    fun setUp() {
    	mockServerHttpRequest = mockk(relaxed = true)
    }
    
    @Test
    fun `test should pass`() {
    	val exchange = createExchange(mockServerHttpRequest)
        assertEquals(exchange.transformlUrl("/foo"), "/foo")
    }
}

 

테스트코드에서 사용되는 두 개의 클래스에 대해서 알아보자.

테스트 레벨사용 목적이 다르다.


1. MockMvc

DispatcherServlet을 포함한 Spring MVC 계층 전체를 대상으로하며

컨트롤러 단위 테스트나 통합 테스트에 사용한다.

 

  • 실제 서블릿 컨테이너(Tomcat 등)를 띄우지 않고 Spring MVC 동작을 시뮬레이션함
  • @Controller, @RestController, @RequestMapping 등을 거쳐가는 전체 요청 처리 과정을 확인할 수 있음
  • andExpect, andDo 같은 체이닝 API로 응답 검증이 가능

2. MockServerHttpRequest

WebFlux(리액티브) 환경에서 주로 사용한다.

서블릿 기반이 아니라 리액티브 스트림 기반 요청을 흉내냄

보통 WebTestClient와 함께 쓰거나, 리액티브 필터/핸들러를 테스트할 때 직접 생성

ServerHttpRequest 객체를 직접 만들어 테스트할 수 있음 → MVC 방식이 아니라 함수형 엔드포인트(WebFlux.fn) 검증 등에 적합

@Test
fun `webflux request test`() {
    val request = MockServerHttpRequest.get("/users/1").build()
    val exchange = MockServerWebExchange.from(request)

    val response = handlerFunction.handle(exchange).block()
    assertEquals(HttpStatus.OK, response?.statusCode)
}