728x90
기획상 게시물에 이미지를 업로드를 해야 하므로, S3를 구축하고 @RequestPart를 사용해서 이미지를 받아올 수 있게 Controller를 수정했다.
Controller를 수정하고 난 뒤, 테스트 코드를 돌려봤더니 400 에러가 발생하고 있었다.
기존 Test code
@Test
@DisplayName("추천글 작성")
void success_post_recommend_test() throws Exception {
RecommendPostRequest request = new RecommendPostRequest("제목", "내용", "유튜브", 100L, 1L);
RecommendPostResponse response = new RecommendPostResponse(1L, "제목", 100L);
given(recommendService.uploadPost(any(), any(), any())).willReturn(response);
String url = "/api/v1/recommends";
mockMvc.perform(post(url).with(csrf())
.header(HttpHeaders.AUTHORIZATION, jwtToken)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(request)))
.andExpect(status().isOk());
}
발생하는 예외는 "Resolved [org.springframework.web.multipart.support.MissingServletRequestPartException: Required part 'request' is not present.]"
request가 현재 존재하지 않는 다는 것.
request는 어디서 존재하고 있는 것일까?
RecommendController
@PostMapping
public Response<RecommendPostResponse> uploadRecommendPost(final Authentication authentication,
@RequestPart(required = false, name = "image") MultipartFile image,
@RequestPart(name = "request") @Valid final RecommendPostRequest request) throws IOException {
String userEmail = authentication.getName();
...
return Response.success(response);
}
해당 컨트롤러를 확인하게 되면 RecommendPostRequest 앞의 @RequestPart(name = "request")로 되어있다.
file 부분을 보게 되면(@RequestPart(required = false) MultipartFile image) required가 false로 되어있기 때문에 따로 image에 대한 내용은 존재하지 않았다.
이제 테스트코드에 request를 만들어야 했다.
Test Code
@Test
@DisplayName("추천글 작성")
void success_post_recommend() throws Exception {
...
MockMultipartFile file = new MockMultipartFile("file", "test.jpg", "image/jpeg",
"test data".getBytes());
MockMultipartFile jsonPart = new MockMultipartFile("request", "request.json",
"application/json", objectMapper.writeValueAsBytes(request));
String url = "/api/v1/recommends";
mockMvc.perform(multipart(url)
.file(file)
.file(jsonPart)
.with(csrf()))
.andExpect(status().isOk());
}
- MockMultipartFile로 Image를 받아오는 file을 하나 생성한다.
- MockMultipartFile로 DTO를 받을 request를 생성한다.
- MockMultipartFile 클래스를 확인해 보면 첫 매개변수에 @RequestPart(name = "request") 여기 name에 해당하는 부분이므로 동일하게 매개변수에 입력하면 된다.
- 두 번째 매개변수에 fileName(임의의 값), 세 번째에 contentType, 마지막으로 objectMapper를 사용하여 request를 Json으로 변환시킨 값을 입력한다.
- perform에서 post(url)이 아닌 multipart(url)로 변경하고. file을 사용하여 생성한 file과 jsonPart를 대입한다.
결과
성공
전체 코드
@WebMvcTest(RecommendRestController.class)
@WithMockCustomOAuth2Account(registrationId = "google")
class RecommendRestControllerTest {
@Autowired
MockMvc mockMvc;
@Autowired
ObjectMapper objectMapper;
@MockBean
RecommendService recommendService;
@MockBean
UserDetailsService userDetailsService;
@MockBean
JwtService jwtService;
String jwtToken;
@BeforeEach
void getToken() {
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
jwtToken = Jwts.builder()
.setSubject("user")
.setIssuer("issuer")
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60))
.signWith(key, SignatureAlgorithm.HS256)
.compact();
}
@Test
@DisplayName("추천글 작성")
void success_post_recommend() throws Exception {
RecommendPostRequest request = new RecommendPostRequest("제목", "내용", "유튜브", 100L, 1L);
RecommendPostResponse response = new RecommendPostResponse(1L, "제목", 100L);
given(recommendService.uploadPost(any(), any(), any())).willReturn(response);
MockMultipartFile file = new MockMultipartFile("file", "test.jpg", "image/jpeg",
"test data".getBytes());
MockMultipartFile jsonPart = new MockMultipartFile("request", "request.json",
"application/json", objectMapper.writeValueAsBytes(request));
String url = "/api/v1/recommends";
mockMvc.perform(multipart(url)
.file(file)
.file(jsonPart)
.with(csrf())
.with(httpBasic("username", "password"))
.header(HttpHeaders.AUTHORIZATION, jwtToken))
.andExpect(status().isOk())
.andExpect(jsonPath("$.resultCode").exists())
.andExpect(jsonPath("$.resultCode").value("SUCCESS"))
.andExpect(jsonPath("$.result.recommendNo").exists())
.andExpect(jsonPath("$.result.recommendNo").value(1))
.andExpect(jsonPath("$.result.recommendTitle").exists())
.andExpect(jsonPath("$.result.recommendTitle").value("제목"))
.andExpect(jsonPath("$.result.recommendPoint").exists())
.andExpect(jsonPath("$.result.recommendPoint").value(100L))
.andDo(print());
}
}
반응형
'Server > Spring&Spring Boot' 카테고리의 다른 글
[Spring Boot] Spring에서 AWS S3에 파일 삭제 요청 보내기 (0) | 2023.02.07 |
---|---|
[Spring Boot] Spring Banner 변경해보기 (Spring boot run!) (2) | 2023.02.01 |
[Junit] 테스트 코드 할 때 가상의 Token 만들어주기 (0) | 2023.01.31 |
[Querydsl] Spring Boot 3.0 이상 Querydsl 세팅 gradle (2) | 2023.01.30 |
[Spring] TomcatServletWebServerFactory Port 설정 (0) | 2023.01.28 |