RestDocs - ClassCastException

2022. 12. 16. 23:28ERROR

 

 @Test
    void 게시글_저장() throws Exception {
        mockMvc.perform(RestDocumentationRequestBuilders.post("/api/v1/posts")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(postCreateDto)))
                .andExpect(status().isOk())
                .andDo(print())
                .andDo(document("post-save",
                        requestFields(
                                fieldWithPath("title").description("게시글 제목"),
                                fieldWithPath("content").description("게시글 내용"),
                                fieldWithPath("writerId").description("작성자 ID")
                        ),
                        responseFields(
                                fieldWithPath("data").type(JsonFieldType.NUMBER).description("게시글 ID"),
                                fieldWithPath("statusCode").type(JsonFieldType.NUMBER).description("상태코드"),
                                fieldWithPath("serverDatetime").type(JsonFieldType.STRING).description("응답 시간")
                        )
                ));
        
    }​
class java.lang.Integer cannot be cast to class java.util.List (java.lang.Integer and java.util.List are in module java.base of loader 'bootstrap')

RestDocs로 문서화를 진행하던 중에 Integer 타입을 List 타입으로 형변환 할 수 없다는 에러가 발생했다.
너무 뚱딴지같은 에러라 디버깅도 해봤는데 원인을 당최 찾기가 어려웠다.

아래 컨트롤러의 register() 메소드를 테스트하고 있었으며

 

문서화를 위해 작성한 테스트 코드는 다음과 같다.

 

RestDocs 익숙한 분들이라면 컨트롤러의 코드만 보고도 에러의 원인을 찾았을 것 같다.

나는 초삽질을 하다가 https://lannstark.tistory.com/10 이 블로그를 보고 탈출할 수 있었다.
API가 객체를 반환하지 않는데 responseFields() 메소드를 사용할 경우 ClassCastException이 발생하게 된단다.

그래서 ApiResponse라는 DTO를 생성해서 반환하도록 변경했다.

    @PostMapping
    public ApiResponse<Long> register(@RequestBody @Valid PostCreateDto createDto) {
        Long savedPostId = postService.register(createDto);

        return ApiResponse.ok(savedPostId);
    }

 

테스트 코드

 @Test
    void 게시글_저장() throws Exception {
        mockMvc.perform(RestDocumentationRequestBuilders.post("/api/v1/posts")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(postCreateDto)))
                .andExpect(status().isOk())
                .andDo(print())
                .andDo(document("post-save",
                        requestFields(
                                fieldWithPath("title").description("게시글 제목"),
                                fieldWithPath("content").description("게시글 내용"),
                                fieldWithPath("writerId").description("작성자 ID")
                        ),
                        responseFields(
                                fieldWithPath("data").type(JsonFieldType.NUMBER).description("게시글 ID"),
                                fieldWithPath("statusCode").type(JsonFieldType.NUMBER).description("상태코드"),
                                fieldWithPath("serverDatetime").type(JsonFieldType.STRING).description("응답 시간")
                        )
                ));
        
    }