org.springframework.restdocs.snippet.SnippetException - The following parts of the payload were not documented - Spring REST Docs 에러

개인 프로젝트 진행중인데 Spring REST Docs API 문서를 작성 중에 이런 오류가 발생했다.
일단 원인은

이렇게 문서화를 위해 컬럼을 만들어 주는건데, 오류에서 보이는 컬럼을 안 만들었다는 오류이다.
그런데 나는 저런 항목을 만든 적이 없다.
구조는 다음과 같다.
코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Getter
@NoArgsConstructor
public class QuizRequest {
private Long randomPlayerId;
private Long userPlayerId;
private int tryCount;
public UsersPickPlayerServiceRequest getUsersPickPlayerServiceRequest() {
return UsersPickPlayerServiceRequest.builder()
.userPickPlayerId(userPlayerId)
.randomPlayerId(randomPlayerId)
.tryCount(tryCount)
.build();
}
@Builder
private QuizRequest(Long randomPlayerId, Long userPlayerId, int tryCount) {
this.randomPlayerId = randomPlayerId;
this.userPlayerId = userPlayerId;
this.tryCount = tryCount;
}
}
다음과 같은 컨트롤러에서 받을 수 있는 Dto 객체를 만들었고
컨트롤러 단에서
1
2
3
4
@PostMapping("/api/v1/pitcher/submit")
public ApiResponse<QuizResponse> submitQuiz(@RequestBody QuizRequest request) {
return ApiResponse.ok(pitcherQueryService.matchRandomPlayerBy(request.getUsersPickPlayerServiceRequest(), LocalDate.now()));
}
다음과 같이 서비스단에 해당 객체를 넘겨준다.
그런데 나는 서비스 단에서 컨트롤러에서 사용하는 객체의 정보를 알고 싶지 않아서 UsersPickPlayerServiceRequest라는 객체를 만들고 컨트롤러 단에서 이 객체로 변환해서 전달 해주도록 설계했다.
1
2
3
4
5
6
7
public UsersPickPlayerServiceRequest getUsersPickPlayerServiceRequest() {
return UsersPickPlayerServiceRequest.builder()
.userPickPlayerId(userPlayerId)
.randomPlayerId(randomPlayerId)
.tryCount(tryCount)
.build();
}
이 메서드로 말이다.
아무튼

간이로 날려보면 정상적으로 동작하는 API이다.
그런데 테스트에서만 지금 문서화가 안된다.
그럼 테스트 코드를 보자.
테스트 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Test
@DisplayName("랜덤선수를 맞춘다.")
void submitQuiz() throws Exception {
.. given 데이터
given(pitcherQueryService.matchRandomPlayerBy(any(UsersPickPlayerServiceRequest.class), any(LocalDate.class)))
.willReturn(quizResponse);
QuizRequest request = QuizRequest.builder()
.randomPlayerId(1L)
.userPlayerId(2L)
.tryCount(2).build();
mockMvc.perform(post("/api/v1/pitcher/submit")
.content(objectMapper.writeValueAsString(request))
.contentType(MediaType.APPLICATION_JSON)
) .andDo(print())
.andExpect(status().isOk())
.andDo(document("pitcher-submit",
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint()),
requestFields(
fieldWithPath("randomPlayerId").type(JsonFieldType.NUMBER).description("랜덤 선수 ID"),
fieldWithPath("userPlayerId").type(JsonFieldType.NUMBER).description("사용자 선택 선수 ID"),
fieldWithPath("tryCount").type(JsonFieldType.NUMBER).description("사용자 도전 횟수 (최대 6)")
), responseFields( ... 생략);
}
지금 responseFields에서 오류가 나는건 아니라 requestFields에서 나기 때문에 다음과 같이 생략했다.
아무튼 나는 QuizRequest의 필드 3개를 타입을 맞춰서 잘 넣어 줬는데 생각지도 않은 이상한 usersPickPlayerServiceRequest 필드를 안만들었다고 오류가 발생한다.
원인을 구글링해서 찾아 보면서도 이 내용은 찾기 힘들었다.
gpt도 잘못 알려준다..
그래서 일단 print()에 찍힌 값을 본다.

진짜로 내가 usersPickPlayerServiceRequest를 보내고 있다…
원인 및 결론
먼저 결론만 말하자면
1
2
3
4
5
6
7
8
9
QuizRequest request = QuizRequest.builder()
.randomPlayerId(1L)
.userPlayerId(2L)
.tryCount(2).build();
mockMvc.perform(post("/api/v1/pitcher/submit")
.content(objectMapper.writeValueAsString(request))
.contentType(MediaType.APPLICATION_JSON)
)
해당 코드 때문이다.
jackson라이브러리에 objectMapper메서드를 사용해서 데이터를 json화 해서 데이터를 넘겼는데,
objectMapper는 객체를 json화 할 때 getter에 접근해서 json 데이터를 만드는 것이다.
그런데 내 QuizRequest에는 다음과 같은 메서드가 있다..
1
2
3
4
5
6
7
public UsersPickPlayerServiceRequest getUsersPickPlayerServiceRequest() {
return UsersPickPlayerServiceRequest.builder()
.userPickPlayerId(userPlayerId)
.randomPlayerId(randomPlayerId)
.tryCount(tryCount)
.build();
}
이거 때문에 계속 usersPickPlayerServiceRequest 필드를 만들어서 보내고 있던 것이었다..
그래서 이름을 getUsersPickPlayerServiceRequest() → toUsersPickPlayerServiceRequest() 로 변경했다.

이제 통과한다 ㅠㅠ
로그를 좀 잘 확인했으면 금방 해결 했을 듯하다.
정작 내가 뭘 보내고 있는지 보지도 않고 다른 빨간 에러 문구만 계속 보니깐 시간이 더 걸렸다.

이렇게 문서도 잘 만들어졌다!!
댓글남기기