@Valid와 BindingResult 또는 Errors
@PostMapping
public ResponseEntity createEvent(@RequestBody @Valid EventDto eventDto, Errors errors) {
if (errors.hasErrors()) {
return ResponseEntity.badRequest().build();
}
Event event = modelMapper.map(eventDto, Event.class);
Event newEvent = eventRepository.save(event);
URI createdUri = linkTo(EventController.class).slash(newEvent.getId()).toUri();
return ResponseEntity.created(createdUri).body(newEvent);
}
@Data @Builder @NoArgsConstructor @AllArgsConstructor
public class EventDto {
@NotEmpty
private String name;
@NotEmpty
private String description;
@NotNull
private LocalDateTime beginEnrollmentDateTime;
@NotNull
private LocalDateTime closeEnrollmentDateTime;
@NotNull
private LocalDateTime beginEventDateTime;
@NotNull
private LocalDateTime endEventDateTime;
private String location;
@Min(0)
private int basePrice;
@Min(0)
private int maxPrice;
@Min(0)
private int limitOfEnrollment;
}
도메인 Validator 만들기
endEventDateTime 가 beginEventDateTime 보다 늦어야 한다.basePrice 가 maxPrice 보다 높을 수 없다.@Component
public class EventValidator {
public void validate(EventDto eventDto, Errors errors) {
if (eventDto.getBasePrice() > eventDto.getMaxPrice() && eventDto.getMaxPrice() > 0) {
errors.rejectValue("basePrice", "wrongValue", "BasePrice is wrong.");
errors.rejectValue("maxPrice", "wrongValue", "maxPrice is wrong.");
}
LocalDateTime endEventDateTime = eventDto.getEndEventDateTime();
if (endEventDateTime.isBefore(eventDto.getBeginEventDateTime())
|| endEventDateTime.isBefore(eventDto.getCloseEnrollmentDateTime())
|| endEventDateTime.isBefore(eventDto.getBeginEnrollmentDateTime())) {
errors.rejectValue("endEventDateTime", "wrongValue", "EndEventDateTime is wrong");
}
}
// TODO BeginEventDateTime
// TODO CloseEnrollmentDateTime
}
테스트 설명용 애노테이션 만들기
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface TestDescription {
String value();
}
@Test
@TestDescription("입력 값이 잘못되어 있는 경우에 에러가 발생하는 테스트")
public void createEvent_Bad_Request_Wrong_Input() throws Exception {