Loading...
Spring Framework Reference Documentation 7.0.2의 Performing Requests의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
This section shows how to use MockMvcTester to perform requests and its integration
with AssertJ to verify responses.
MockMvcTester는 요청을 구성하기 위한 fluent API를 제공하며, 이는 Hamcrest support와 동일한
MockHttpServletRequestBuilder를 재사용하지만 static method를 import할 필요는 없습니다.
반환되는 builder는 AssertJ-aware이므로 일반적인 assertThat() factory method로 이를 감싸면
exchange가 트리거되고 MvcTestResult에 대한 전용 Assert 객체에 접근할 수 있게 됩니다.
다음은 /hotels/42에 대해 POST를 수행하고 요청에 Accept 헤더를 지정하도록
구성하는 간단한 예제입니다:
1assertThat(mockMvc.post().uri("/hotels/{id}", 42).accept(MediaType.APPLICATION_JSON)) 2 . // ...Copied!
1assertThat(mockMvc.post().uri("/hotels/{id}", 42).accept(MediaType.APPLICATION_JSON)) 2 . // ...Copied!
AssertJ는 종종 exchange의 다양한 부분을 검증하기 위해 여러 개의 assertThat() 구문으로 구성됩니다.
위의 경우처럼 하나의 구문만 사용하는 대신, .exchange()를 사용하여 여러 개의
assertThat 구문에서 사용할 수 있는 MvcTestResult를 반환할 수 있습니다:
1MvcTestResult result = mockMvc.post().uri("/hotels/{id}", 42) 2 .accept(MediaType.APPLICATION_JSON).exchange(); 3assertThat(result). // ...Copied!
1val result = mockMvc.post().uri("/hotels/{id}", 42) 2 .accept(MediaType.APPLICATION_JSON).exchange() 3assertThat(result) 4 . // ...Copied!
다음 예제에서 보듯이 URI 템플릿 스타일로 쿼리 파라미터를 지정할 수 있습니다:
1assertThat(mockMvc.get().uri("/hotels?thing={thing}", "somewhere")) 2 . // ...Copied!
1assertThat(mockMvc.get().uri("/hotels?thing={thing}", "somewhere")) 2 . // ...Copied!
또한 다음 예제에서 보듯이 쿼리 또는 폼 파라미터를 나타내는 Servlet 요청 파라미터를 추가할 수도 있습니다:
1assertThat(mockMvc.get().uri("/hotels").param("thing", "somewhere")) 2 . // ...Copied!
1assertThat(mockMvc.get().uri("/hotels").param("thing", "somewhere")) 2 . // ...Copied!
애플리케이션 코드가 Servlet 요청 파라미터에 의존하고 쿼리 스트링을 명시적으로 확인하지 않는다면
(대부분의 경우가 그러함), 어떤 옵션을 사용하든 상관없습니다.
그러나 URI 템플릿로 제공된 쿼리 파라미터는 디코딩되는 반면, param(…) 메서드를 통해 제공된 요청 파라미터는 이미
디코딩된 것으로 간주된다는 점을 명심해야 합니다.
요청 처리가 비동기식으로 수행되는 경우, exchange()는 요청이 완료될 때까지
대기하므로 assert할 결과는 사실상 변경 불가능합니다.
기본 타임아웃은 10초이지만, 다음 예제에서 보듯이 요청별로 이를 제어할 수 있습니다:
1assertThat(mockMvc.get().uri("/compute").exchange(Duration.ofSeconds(5))) 2 . // ...Copied!
1assertThat(mockMvc.get().uri("/compute").exchange(Duration.ofSeconds(5))) 2 . // ...Copied!
비동기 요청의 라이프사이클을 직접 관리하고 raw 결과를 얻고 싶다면,
exchange 대신 asyncExchange를 사용하십시오.
MockMultipartHttpServletRequest를 내부적으로 사용하는 파일 업로드 요청을 수행할 수 있으므로
multipart 요청에 대한 실제 파싱은 수행되지 않습니다.
대신, 다음 예제와 유사하게
설정해야 합니다:
1assertThat(mockMvc.post().uri("/upload").multipart() 2 .file("file1.txt", "Hello".getBytes(StandardCharsets.UTF_8)) 3 .file("file2.txt", "World".getBytes(StandardCharsets.UTF_8))) 4 . // ...Copied!
1assertThat(mockMvc.post().uri("/upload").multipart() 2 .file("file1.txt", "Hello".toByteArray(StandardCharsets.UTF_8)) 3 .file("file2.txt", "World".toByteArray(StandardCharsets.UTF_8))) 4 . // ...Copied!
대부분의 경우, 요청 URI에서 컨텍스트 경로와 Servlet 경로를 생략하는 것이 바람직합니다.
전체 요청 URI로 테스트해야만 한다면, 다음 예제에서 보듯이 요청 매핑이 동작하도록
contextPath와 servletPath를 적절히 설정해야 합니다:
1assertThat(mockMvc.get().uri("/app/main/hotels/{id}", 42) 2 .contextPath("/app").servletPath("/main")) 3 . // ...Copied!
1assertThat(mockMvc.get().uri("/app/main/hotels/{id}", 42) 2 .contextPath("/app").servletPath("/main")) 3 . // ...Copied!
앞선 예제에서처럼 매번 수행되는 요청마다 contextPath와
servletPath를 설정하는 것은 번거로울 수 있습니다.
대신, 다음 예제에서 보듯이
기본 요청 프로퍼티를 설정할 수 있습니다:
1MockMvcTester mockMvc = MockMvcTester.of(List.of(new HotelController()), 2 builder -> builder.defaultRequest(get("/") 3 .contextPath("/app").servletPath("/main") 4 .accept(MediaType.APPLICATION_JSON)).build());Copied!
1val mockMvc = 2 MockMvcTester.of(listOf(HotelController())) { builder: StandaloneMockMvcBuilder -> 3 builder.defaultRequest<StandaloneMockMvcBuilder>( 4 MockMvcRequestBuilders.get("/") 5 .contextPath("/app").servletPath("/main") 6 .accept(MediaType.APPLICATION_JSON) 7 ).build() 8 }Copied!
앞에서 언급한 프로퍼티는 mockMvc 인스턴스를 통해 수행되는 모든 요청에 영향을 줍니다.
동일한 프로퍼티가 특정 요청에 대해서도 지정된 경우, 해당 값은 기본값을 오버라이드합니다.
이 때문에 기본 요청의 HTTP 메서드와 URI는 중요하지 않은데, 이는 모든 요청에서 반드시
지정되어야 하기 때문입니다.
Configuring MockMvcTester
Defining Expectations