MockMvc를 이용하여 Controller 테스트 코드를 작성한다.
테스트할 코드는 form-data 형식으로 이미지 파일과 텍스트를 입력 받아 유저 리소스를 수정하는 PATCH 메서드이다.
1. MockMultipartFile 객체 생성
MockMultipartFile file = new MockMultipartFile(
"홍길동전 썸네일 이미지",
"thumbnail.png",
MediaType.IMAGE_PNG_VALUE,
"thumbnail".getBytes()
);
MockMulipartFile은 MultipartFile 인터페이스를 상속 받는 가짜 객체다.
multipart 파일을 업로드하는 컨트롤러 테스트에 사용된다.
2. 요청
mockMvc.perform(
multipart(HttpMethod.PATCH, BASE_URL + "/profile")
.file(file)
.param("nickName", nickname)
.with(csrf()));
- perform.patch()가 아닌 perform(multipart())로 요청한다.
- HttpMethod.PATCH를 입력 매개변수의 첫 번째 위치에 넣어준다.
multipart()는 기본적으로 POST로 하드 코딩되어 있다. 하지만 내부 코드에 Http Method를 매개변수로 받을 수 있도록 오버 로딩되어 있다.
- CSRF 토큰에 대한 문제로 발생하므로 .with(csrf())를 추가한다.
받은 요청에 CSRF 토큰이 담겨있지 않아 세션에 저장된 CSRF 값과 비교할 수 없어 403 Forbidden 에러가 발생하게 된다.
✏️ CSRF(Cross-Site-Request Forgery)란?
악의적인 코드를 심어놓은 사이트에서 로그인한 사용자가 클릭하게 하여 사용자의 의지와 무관한 요청을 발생시키는 공격을 의미한다.
Spring Security에서는 이를 방지하기 위해 "CSRF Token"을 이용해 토큰을 비교한 뒤 일치하는 경우에만 메서드를 정상적으로 실행하게 만든다.
참고로 RESTFul한 웹 서비스에서는 대부분 비활성화로 설정한다고 한다.
REST API는 대부분 무상태성을 유지하며, JWT와 같은 토큰 방식으로 인증하기 때문에 요청이 세션에 의존하지 않기 때문이다.
3. 전체 코드
@Test
@DisplayName("유저는 자신의 프로필을 수정할 수 있다.")
public void updateUserProfile() throws Exception {
// given
String nickname = "닉네임1";
MockMultipartFile file = new MockMultipartFile(
"홍길동전 썸네일 이미지",
"thumbnail.png",
MediaType.IMAGE_PNG_VALUE,
"thumbnail".getBytes()
);
// when
ResultActions result =
mockMvc.perform(
multipart(HttpMethod.PATCH, BASE_URL + "/profile")
.file(file)
.param("nickName", nickname)
.with(csrf()));
// then
result.andExpect(status().isOk())
.andExpect(jsonPath("$.data").isNotEmpty())
.andExpect(jsonPath("$.data", "성공적으로 프로필이 업데이트 되었습니다.").exists());
}
Reference
[SpringBoot] MockMvc - multipart() POST외 다른 HTTPMethod 사용하기
개발 환경 Build : Gradle SpringBoot : 2.7.5 Java : 11 OS : Mac 요구사항 RestDocs API 문서화를 위해 MockMvc를 이용하여 Controller 테스트 코드를 작성해야 함. 테스트할 코드는 form-data로 이미지 파일과 텍스트를
wonkang.tistory.com
[TroubleShooting] SpringBoot Controller Test - MockMvc 302 Found, 403 Forbidden
개발 환경 Build : Gradle SpringBoot : 2.7.5 Java : 11 OS : Mac 발생 - 403 Forbidden RestDocs를 사용하여 API 문서화 작업을 하려고 Controller에서 테스트 코드를 작성 후 테스트를 진행하였고, 403 Forbidden 에러가 발
wonkang.tistory.com
'Framework > Spring' 카테고리의 다른 글
[SpringBoot] 다중 DB 구성하기 (0) | 2024.05.11 |
---|---|
[SpringBoot] @Async로 비동기 처리하기 (0) | 2024.04.18 |
[SpringBoot] 외부 API 호출하기(2) (0) | 2024.04.18 |
[SpringBoot] 외부 API 호출하기(1) (2) | 2024.04.18 |