[Spring] mockito @Valid 를 이용한 유형성 검증 ,예외 , 페이징 테스트

hyewon jeong·2023년 3월 11일
0

Spring

목록 보기
39/59

📌 @valid 테스트

  1. @Valid 에 유효하지 않은 값을 넣을 때 어떤 결과가 발생할까?
    포스트맨으로 확인 결과 Status 400 에러와 must not be Blank라는 @valid디폴트 메시지가 출력 되었다.

하지만 must not be Blank 넣으면 아래와 같이 실패하게 된다.
@valid 디폴트 메세지가 must not be Blank or 한글로는 "공백일 수 없습니다." 이다.

그래서 아래와 같이 바꾸니 성공했다.

FaqRequest

@Getter
@NoArgsConstructor(force = true, access = AccessLevel.PROTECTED)
public class FaqRequest {
  @NotBlank
  private final String question;
  @NotBlank
  private final String answer;

FaqService

 @Override
 public void saveFaq(@Valid FaqRequest faqRequest, Long managerId) {
   Faq faq = faqRequest.toEntity(managerId);
   faqRepository.save(faq);
 }

하나하나 살펴보기

Test code

  private static ValidatorFactory factory;
  private static Validator validator;

  @BeforeAll
  public static void init() {
    factory = Validation.buildDefaultValidatorFactory();
    validator = factory.getValidator();
  }

  @AfterAll
  public static void close() {
    factory.close();
  }
  /**

  @Test
  @DisplayName("FAQ 등록_실패 request에 @NotBlank 아닐때")
  void saveFaq_valid_fail() {

    //given
    FaqRequest faqRequest = new FaqRequest("", "1111");
    //when
    Set<ConstraintViolation<FaqRequest>> violation = validator.validate(faqRequest);
    //then
    assertThat(violation).isNotEmpty();
    violation
        .forEach(error -> {
          assertThat(error.getMessage()).isEqualTo("공백일 수 없습니다");
        });
  }

제약조건에 대한 유효성검증

제약조건의 확인은 javax.validation.Validator 를 사용해서 이루어집니다.

가장 쉽고 빠르게 Validator 를 가져오는 방법은 ValidatorFactory 를 사용하는 방법입니다.

그리고 validate() 를 사용해서 빈의 유효성검증을 실행합니다.
제약조건을 위반한 내용은 ConstraintViolation 인터페이스로 반환됩니다.

제약조건 위반내용에 대한 확인
위반내용은 아래와 같이 ConstraintViolation 인터페이스에 포함되어 있습니다.

(1) ValidatorFactory factory

초기화된 유효성 검사기 인스턴스를 반환하는 팩토리

(2) buildDefaultValidatorFactory()

(1) ConstraintViolation?

이 개체는 제약 조건 위반 컨텍스트와 위반을 설명하는 메시지를 노출합니다.

📌 예외 테스트

import static org.junit.jupiter.api.Assertions.assertThrows;

의 AssertThrows 이용한 예외 테스트

FaqSercive

  @Override
  public FaqResponse getSelectedFaq(Long id) {
    Faq faq = faqRepository.findById(id).orElseThrow(
        () -> new CustomException(ExceptionStatus.BOARD_NOT_EXIST)
    );
    return new FaqResponse(faq);
  }

Test code


  @Test
  @DisplayName("FAQ 건당조회_id가 없을때 예외")
  void getSelectedFaq_throw() {
    //given
    when(faqRepository.findById(anyLong()))
        .thenReturn(Optional.empty());
    //when&then
    assertThrows(CustomException.class, () -> {
      faqServiceImpl.getSelectedFaq(1L);
    });
  }

Mock 객체의 메서드 호출시 예외를 발생시키고 싶을 때

thenThrow()를 이용한 예외 발생

Mock 객체의 메서드 호출시 예외를 발생시키고 싶을 때가 있는데, 이런 경우에는 thenThrow() 메서드를 사용하면 된다

[SpringBoot] @Valid를 이용한 유효성 검증
23.01.31 ~3.11 mockito 이용 단위테스트 시 에러들

페이징 처리 된 조회 테스트

페이징처리는 테스는 코드 큰 의미 없다.
스프링부트를 돌려봐야 , 페이지처리 가 잘된지 알 수 있다.
그래서 if 분기에 대한 것만 테스트 코드를 작성했다.

FaqService

 @Override
 public Result getFaqList(int page, int size, Direction direction, String properties) {
   Page<Faq> faqListPage = faqRepository.findAll(
       PageRequest.of(page - 1, size, direction, properties));
   int totalCount = (int) faqListPage.getTotalElements();
   if (faqListPage.isEmpty()) {
     throw new CustomException(ExceptionStatus.POST_IS_EMPTY);
   }

   List<FaqResponse> faqResponses = faqListPage.stream().map(FaqResponse::new)
       .collect(Collectors.toList());
   int countList = size;
   int countPage = 5;//todo 리팩토링때  10으로 변경예정
   int totalPage = totalCount / countList;
   if (totalCount % countList > 0) {
     totalPage++;
   }
   if (totalPage < page) {
     page = totalPage;
   }
   return new Result(page, totalCount, countPage, totalPage, faqResponses);
 }

Test code

  @Test
  @DisplayName("FAQ 조회_글이 없을때 예외발생")
  void getFaqList_throw() {
    //given
    int page =1 ;
    int size =10;
    Direction direction = Direction.DESC;
    String properties = "createdDate";

    lenient().when(faqRepository.findAll(PageRequest.of(page-1,size,direction,properties)))
        .thenReturn(Page.empty());
    //when&then
    assertThrows(CustomException.class,()->{
      faqServiceImpl.getFaqList(page,size,direction,properties);
        });
  }
profile
개발자꿈나무

0개의 댓글