2 분 소요

개인 프로젝트 진행중인데 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 데이터를 만드는 것이다.

bactoria님 - ObjectMapper는 Property를 어떻게 찾을까 ?

그런데 내 QuizRequest에는 다음과 같은 메서드가 있다..

1
2
3
4
5
6
7
public UsersPickPlayerServiceRequest getUsersPickPlayerServiceRequest() {  
	return UsersPickPlayerServiceRequest.builder()  
			.userPickPlayerId(userPlayerId)  
			.randomPlayerId(randomPlayerId)  
			.tryCount(tryCount)  
			.build();  
}

이거 때문에 계속 usersPickPlayerServiceRequest 필드를 만들어서 보내고 있던 것이었다..

그래서 이름을 getUsersPickPlayerServiceRequest()toUsersPickPlayerServiceRequest() 로 변경했다.

이제 통과한다 ㅠㅠ

로그를 좀 잘 확인했으면 금방 해결 했을 듯하다.

정작 내가 뭘 보내고 있는지 보지도 않고 다른 빨간 에러 문구만 계속 보니깐 시간이 더 걸렸다.

이렇게 문서도 잘 만들어졌다!!

댓글남기기