과제를 하다가 처음으로 테스트 코드를 작성했다... 쉽지 않았다. 생각은 쉽게 했지만, 처음하면 많은 것에 부딪친다. 하지만, 이 역시 이겨내리라. The Top of Iceberg!
테스트 코드를 처음으로 작성해봤는데, 처음에는 그럭저럭 넘어갈만했다. 하지만, @AuthenticationPrincipal
을 어떻게 처리해줘야할지... 막막했고 구글링을 했다.
역시 결과가 중요하다. 결과부터 소개한다.
.with(SecurityMockMvcRequestPostProcessors.user(principalDetails))
을 이용하면 된다. 테스트 코드의 전문은 아래와 같다.
@Test
@Order(1)
@DisplayName("게시글 생성 테스트")
public void postBoardTest() throws Exception {
//given
// 1번 : 멤버를 만든다.
Member member = new Member(1L, aes256.encrypt( "test@gmail.com"), aes256.encrypt("password"),"ROLE_USER");
memberRepository.save(member);
PrincipalDetails principalDetails = new PrincipalDetails(memberRepository.findById(1L).get());
BoardPostDto boardPostDto = new BoardPostDto("test : title", "test : description");
String content = gson.toJson(boardPostDto);
//when
ResultActions actions = mockMvc.perform(
MockMvcRequestBuilders.post("/board/post")
// 2번 : SecurityMockMvcRequestPostProcessors의 user 메서드를 이용한다. (끝)
.with(SecurityMockMvcRequestPostProcessors.user(principalDetails)) // @AuthenticationPrincipal 해결.
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content(content)
);
//then
MvcResult result = actions
.andExpect(status().isCreated())
.andExpect(jsonPath("$.title").value(boardPostDto.getTitle()))
.andExpect(jsonPath("$.description").value(boardPostDto.getDescription()))
.andReturn();
System.out.println(result.getResponse().getContentAsString());
}
아래 사진을 보면 SecurityMockMvcRequestPostProcessors
클래스 내부의 user
메서드는 String과 UserDetails를 파라미터로 받는다. 그리고 Authentication.getPrincipal()을 가능하게 하는 SecurityContext를 만드는 객체 UserDetailsRequestPostProcessor
를 반환한다.
UserDetailsRequestPostProcessor
는 RequestPostProcessor
을 구현했다.
그래서 MockHttpServletRequestBuilder.with(바로 여기)
의 파라미터로 사용이 가능하다.
📌 지금까지 위의 구조로 아래와 같은 코드로 구현할 수 있었다.
SecurityMockMvcRequestPostProcessors의 user()
는 Authentication.getPrincipal()
을 가능하게 하는 UserRequestPostProcessor
를 반환한다.
UserRequestPostProcessor
은 RequestPostProcessor
인터페이스를 구현한다.
UserRequestPostProcessor
는 MockHttpServletRequestBuilder.with(RequestPostProcessor postProcessor)
의 파라미터로 사용이 가능한다.
.with(SecurityMockMvcRequestPostProcessors.user(principalDetails))
을 사용하면, 테스트 시 @AuthenticationPrincipal
의 파라미터로 넘겨주면서 테스트가 가능하다.