RestDocs에서의 SpringSecurity Issue
571
작성한 질문수 7
public class FollowControllerDocsTest extends RestDocsSupport {
private FollowService followService = mock(FollowService.class);
@Override
protected Object initController() {
return new FollowController(followService);
}
private final Long loginUserId = 1L;
@DisplayName("팔로우 수행 API")
@WithUserDetails
@Test
public void startFollow() throws Exception {
// Given
StartFollowRequestDto requestDto = StartFollowRequestDto.builder()
.followerId(loginUserId)
.followingId(123L)
.build();
BDDMockito.doReturn(StartFollowResponseDto.success())
.when(followService)
.follow(any(StartFollowRequestDto.class));
//when,then
mockMvc.perform(
post("/api/follow/start-follow")
.with(csrf())
.content(objectMapper.writeValueAsString(requestDto))
.contentType(MediaType.APPLICATION_JSON)
)
.andExpect(status().isOk())
.andDo(document("start-follow",
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint()),
requestFields(
fieldWithPath("followerId").type(JsonFieldType.STRING)
.optional()
.description("팔로워 아이디"),
fieldWithPath("followingId").type(JsonFieldType.STRING)
.optional()
.description("팔로잉 아이디")
),
responseFields(
fieldWithPath("code").type(JsonFieldType.STRING)
.description(ResponseCode.SUCCESS),
fieldWithPath("message").type(JsonFieldType.STRING)
.description(SUCCESS)
)
));
}
}
FollowController
@RestController
@RequestMapping("/api/follow")
@RequiredArgsConstructor
public class FollowController {
private final FollowService followService;
@PostMapping("/start-follow")
ResponseEntity<? super StartFollowResponseDto> startFollow(
@RequestBody @Valid StartFollowRequestDto requestBody,
@AuthenticationPrincipal PrincipalDetails principalDetails
) {
Long loginId = principalDetails.getUser().getId();
Long userId = requestBody.getFollowerId();
if (loginId != userId) return StartFollowResponseDto.certificationFail();
ResponseEntity<? super StartFollowResponseDto> response = followService.follow(requestBody);
return response;
}
}
RestDocsSupport
@ExtendWith(RestDocumentationExtension.class)
public abstract class RestDocsSupport {
protected MockMvc mockMvc;
protected ObjectMapper objectMapper = new ObjectMapper();
private final Long loginUserId = 1L;
@BeforeEach
void setUp(RestDocumentationContextProvider provider) {
User user = mock(User.class);
when(user.getId()).thenReturn(loginUserId);
PrincipalDetails userDetails = mock(PrincipalDetails.class);
when(userDetails.getUser()).thenReturn(user);
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(new UsernamePasswordAuthenticationToken(userDetails, null, null));
this.mockMvc = MockMvcBuilders
.standaloneSetup(initController())
.apply(MockMvcRestDocumentation.documentationConfiguration(provider))
.build();
System.out.println("beforeEach 수행");
}
protected abstract Object initController();
}
안녕하세요. 강의 정말 유익하게 잘 듣고있습니다. 강의를 듣고 restdocs를 작성하던 중 문제가 발생하여 질문을 올립니다.
제가 작성한 controller에서는 파라미터로 security.context 안에 있는 PrincipalDetails를 받아옵니다.
그렇지만 테스트에선 그 안에 값이 있는게 아니여서 Mock값을 넣어주어 @WebMvcTest 에서는 문제를 해결해 왔었습니다.
문제는 restdocs를 작성하기 위한 테스트 코드에서 발생하였습니다. 이 테스트 코드에는 제가 적용한 PrincipalDetails 몫 이 넣어지지 않는 문제가 있었습니다.
제가 생각하기론 SpringSecurity가 올라가지 않아서 그런 것 같은데 해결방법이 있으면 알고싶습니다 !
답변 2
0
안녕하세요, 김승수 님!
질문 주신 내용에 대해 제가 하나하나 알려드리기 보다는, Security와 관련해서 테스트를 할 때에 대표적으로 많이 사용하는 @WithMockUser 어노테이션 등에 대해서 한번 찾아보고 적용해보시기를 권합니다. ㅎㅎ
추가로 남겨주신 질문에 대해서,
@WebMvcTest 에 @AutoConfigureRestDocs 을 붙여서 하고 있는데 이렇게 해도 상관없는지
네, 상관 없습니다.
validation exception 이 발생하는 api 테스트도 문서로 작성을 모두 해야하는지
해야 한다기 보다는 여유가 된다면 하면 좋은 것이겠죠?
내가 만든 API, 우리 팀이 제공하는 API를 외부 팀에게 어느 수준까지 정보를 제공해주면 좋을지 고민해보고 결정하면 될 문제 같습니다. ㅎㅎ
감사합니다 🙂
0
아 그리고 !지금은 @WebMvcTest 에 @AutoConfigureRestDocs 을 붙여서 하고 있는데 이렇게 해도 상관없는지도 알고싶습니다 ! 추가로 validation exception 이 발생하는 api 테스트도 문서로 작성을 모두 해야하는지 궁금합니다.!
private 상수 테스트 관련 질문
0
82
1
void는 어떻게 테스트하나요..? void로 애초에 코딩하면 안되나요??
0
124
2
커버리지는 어떻게 활용하시는지 궁금합니다.
0
159
2
테스트 문서화 질문입니다
0
104
2
단위테스트 질문이 있습니다
0
94
2
컨트롤러는 모킹을 한 이유가 궁금합니다.
0
100
2
ERD 가장자리에 있는 도메인 테스트 질문
0
87
2
DTO 검증 필드에 대한 테스트 코드 작성은 어디까지?
0
132
2
OrderCreateRequest DTO에 대해서 궁금한점
0
101
2
고전파의 테스트 대역 사용 대상, 공유 의존성
0
154
2
계층 관련 질문이 있습니다.
0
137
3
'코틀린'에서는 빌더를 따로 쓰지 않는데, 이 때는 어떻게 test fixture를 만드시는지 궁금합니다
1
122
2
혹시 update 로직은 어떻게 테스트하나요? (@Setter?)
0
133
2
단위테스트와 통합테스트의 경계가 궁금합니다.
0
227
2
Service+Repository 통합테스트 관련 질문입니다.
0
149
2
OrderControllerDocsTest 작성 해봤는데요. 날짜 형식이 이상하게 나와요
0
183
2
test 용 .yml
0
89
2
throws Exception
0
78
2
카페키오스크 클래스 문의 ,,
0
87
2
Rest docs 문서용 테스트코드를 따로 작성해야 되나요?
0
171
2
테스트 코드에서 필요한 생성자
0
137
1
tearDown 순서
0
115
2
@Builder 생성자 private
0
135
2
@DisplayName gradle / intellJ
0
92
2





