본문 바로가기

Dev/Spring Boot

[Validation] @Past, @FutureOrPresent LocalDateTime 타입 검증 이슈

TimeDto.java

@ToString
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor
@Getter
@Builder
public class TimeDto {

    // ##### Date #####
    @Future
    private LocalDate futureDate;

    @FutureOrPresent
    private LocalDate futureOrPresentDate;

    @Past
    private LocalDate pastDate;

    @PastOrPresent
    private LocalDate pastOrPresentDate;

    // ##### Time #####
    @Future
    private LocalDateTime futureTime;

    @FutureOrPresent
    private LocalDateTime futureOrPresentTime;

    @Past
    private LocalDateTime pastTime;

    @PastOrPresent
    private LocalDateTime pastOrPresentTime;

}

 

@Past 테스트 코드

@Test
@DisplayName("Past : now")
void numberDto5() throws Exception {
    TimeDto timeDto = TimeDto.builder() 
            .pastTime(now)
            .build();

    mvc.perform(post(EndPoint.TIME_ENDPOINT.getEndPoint())
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(new ObjectMapper().registerModule(new JavaTimeModule()).writeValueAsString(timeDto)))
            .andExpect(status().isBadRequest());
}

LocalDateTime.now() 로 API 호출하였으나 과거 값 검증에 통과하지 못함.

  • Expected : 400
  • Actual : 200

 

@FutureOrPresent 테스트 코드

@Test
@DisplayName("FutureOrPresent : now")
void numberDto5() throws Exception {
    TimeDto timeDto = TimeDto.builder()
            .futureOrPresentTime(LocalDateTime.now())
            .build();

    mvc.perform(post(EndPoint.TIME_ENDPOINT.getEndPoint())
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(new ObjectMapper().registerModule(new JavaTimeModule()).writeValueAsString(timeDto)))
            .andExpect(status().isOk());
}

LocalDateTime.now() 로 API 호출하였으나 현재 또는 미래 값 검증에 통과하지 못함.

- Expected : 200

- Actual   : 400

 

정리

비교 대상을 주의해야 한다.

1. @Past

  • now : 테스트 코드에서 생성한 LocalDateTime.now()
  • now 는 [Api 호출 시점]이 아니라 [Api 호출 후 검증 로직에 들어간 시점 AbstractJavaTimeValidator isValid ()] 과 비교 된다.
  • [now].compareTo([Api 호출 후 검증 로직에 들어간 시점]) = -1 (과거) 이므로 valid 로 리턴한다.

2. @FutureOr Present

  • now : 테스트 코드에서 생성한 LocalDateTime.now()
  • now 는 [Api 호출 시점]이 아니라 [Api 호출 후 검증 로직에 들어간 시점 AbstractJavaTimeValidator isValid ()] 과 비교 된다.
  • [now].compareTo([Api 호출 후 검증 로직에 들어간 시점]) = -1 (과거) 이므로 inValid 로 리턴한다.