[Spring] 스프링 Rest Docs 작성중 SnippetException: The following parts of the payload were not documented 에러

kai6666·2022년 7월 18일
4

TIL. Spring

목록 보기
8/11
post-custom-banner

에러 코드 (테스트 실패)

getActions
                .andExpect(status().isOk())
                .andDo(
                        document(
                                "get-members",
                                getRequestPreProcessor(),
                                getResponsePreProcessor(),
                                requestParameters(
                                        List.of(
                                        parameterWithName("page").description("페이지 번호"),
                                        parameterWithName("size").description("페이지 사이즈")
                                )),
                                responseFields(
                                        List.of(
                                                fieldWithPath("data").type(JsonFieldType.OBJECT).description("결과 데이터"),
                                                fieldWithPath("data[].memberId").type(JsonFieldType.NUMBER).description("회원 식별자"),
                                                fieldWithPath("data[].name").type(JsonFieldType.STRING).description("이름"),
                                                fieldWithPath("data[].phone").type(JsonFieldType.STRING).description("휴대폰 번호"),
                                                fieldWithPath("data[].email").type(JsonFieldType.STRING).description("이메일"),
                                                fieldWithPath("data[].memberStatus").type(JsonFieldType.STRING).description("회원 상태: MEMBER_ACTIVE(활동중) / MEMBER_SLEEP(휴면 계정) / MEMBER_QUIT(탈퇴)"),
                                                fieldWithPath("data[].stamp").type(JsonFieldType.NUMBER).description("스탬프 갯수")
                                        )
                                )
                        )
                );

통과 코드 (테스트 통과)


       getActions
               .andExpect(status().isOk())
               .andDo(
                       document(
                               "get-members",
                               getRequestPreProcessor(),
                               getResponsePreProcessor(),
                               requestParameters(
                                       List.of(
                                       parameterWithName("page").description("페이지 번호"),
                                       parameterWithName("size").description("페이지 사이즈")
                               )),
                               responseFields(
                                       List.of(
                                               fieldWithPath("data").type(JsonFieldType.ARRAY).description("결과 데이터"),
                                               fieldWithPath("data[].memberId").type(JsonFieldType.NUMBER).description("회원 식별자"),
                                               fieldWithPath("data[].name").type(JsonFieldType.STRING).description("이름"),
                                               fieldWithPath("data[].phone").type(JsonFieldType.STRING).description("휴대폰 번호"),
                                               fieldWithPath("data[].email").type(JsonFieldType.STRING).description("이메일"),
                                               fieldWithPath("data[].memberStatus").type(JsonFieldType.STRING).description("회원 상태: MEMBER_ACTIVE(활동중) / MEMBER_SLEEP(휴면 계정) / MEMBER_QUIT(탈퇴)"),
                                               fieldWithPath("data[].stamp").type(JsonFieldType.NUMBER).description("스탬프 갯수"),

                                               fieldWithPath("pageInfo").type(JsonFieldType.OBJECT).description("페이지 정보"),
                                               fieldWithPath("pageInfo.page").type(JsonFieldType.NUMBER).description("페이지 정보"),
                                               fieldWithPath("pageInfo.size").type(JsonFieldType.NUMBER).description("사이즈 정보"),
                                               fieldWithPath("pageInfo.totalElements").type(JsonFieldType.NUMBER).description("전체 조회 건 수"),
                                               fieldWithPath("pageInfo.totalPages").type(JsonFieldType.NUMBER).description("전체 페이지 수")
                                       )
                               )
                       )
               )
               .andReturn();


😵‍💫 에러 메시지

The following parts of the payload were not documented:
{
  "pageInfo" : {
    "page" : 1,
    "size" : 2,
    "totalElements" : 2,
    "totalPages" : 1
  }
}
org.springframework.restdocs.snippet.SnippetException: The following parts of the payload were not documented:
{
  "pageInfo" : {
    "page" : 1,
    "size" : 2,
    "totalElements" : 2,
    "totalPages" : 1
  }
}
  • 에러 메시지를 보면 pageInfo 부분의 payload were not documented라고 한다.
  • payload전송되는 데이터를 의미한다. 즉 pageInfo 데이터가 전송되는 과정에서 문서화가 안 되는 것이다. (문서화할 때 회원 전체 조회 하단에 페이지 정보를 제공하는 것을 목표하고 있다.)

❓ SnippetException

  • SnippetException은 런타임 익셉션 에러 중 하나로, 스니펫 생성시 문제가 발생할 때 던져진다. (thrown to indicate a problem with the generation of a document snippet) 따라서 스니펫 생성에 대해 자세히 알아볼 필요가 있다.



스프링 REST Docs 공식문서의 Documenting your API 부분의 Request Parameters 부분 전문이다. 여기서 SnippetException 에러와 관련 깊은 부분은 아래와 같다.

When documenting request parameters, the test will fail if an undocumented request parameter is used in the request. Similarly, the test will also fail if a documented request parameter is not found in the request.

  • 리퀘스트 파라미터를 문서화하지 않았을 때
  • 문서화 된 리퀘스트 파라미터가 리퀘스트에 없을 때
    리퀘스트 파라미터로 인해 테스트가 실패한다. 내 코드의 경우는 리퀘스트 파라미터가 있는데 문서화하지 않아서 SnippetException 가 발생한 것이다.


해결 - responseFields에 pageInfo 추가

fieldWithPath("pageInfo").type(JsonFieldType.OBJECT).description("페이지 정보"),
fieldWithPath("pageInfo.page").type(JsonFieldType.NUMBER).description("페이지 정보"),
fieldWithPath("pageInfo.size").type(JsonFieldType.NUMBER).description("사이즈 정보"),
fieldWithPath("pageInfo.totalElements").type(JsonFieldType.NUMBER).description("전체 조회 건 수"),
fieldWithPath("pageInfo.totalPages").type(JsonFieldType.NUMBER).description("전체 페이지 수")

.andDo(document(...)) 안의 responseFieldspageInfo에 해당하는 전송 데이터를 추가해주었다. 생각해보면 response에 뜨길 바라는 데이터는 애초에 넣는 것이 자연스럽긴 하다.

requestParameters(
	List.of(
 		parameterWithName("page").description("페이지 번호").ignored(),
		parameterWithName("size").description("페이지 사이즈").ignored()
			)),

번외지만, 공식 문서에 나왔듯이 문서에 리퀘스트 파라미터를 드러내고 싶지 않으면 .ignored()를 붙이면 된다고 한다.

그리고 통과된 코드의 마지막을 보면.andReturn()이 추가 되어있다. 넣어도 빼도 테스트는 통과한다. .andReturn()HTTP 통신시 주고 받는 값을 가져올 수 있는 기능으로, 사진처럼 다양한 메서드와 함께 써서 값을 변수에 바로 담아서 활용할 수 있게 해준다. (처음엔 이것만 추가하면 documentation도 처리되는줄 알았는데, 스니펫 문서화와 값을 받는 기능은 완전히 다른 동작이다.)



참고 자료

profile
성장 아카이브
post-custom-banner

0개의 댓글