@valid 테스트하기

HMS·2024년 1월 13일

@Valid를 사용하는 객체들이 잘 작동하는지 확인하기 위해 테스트 코드를 작성 방법을 찾아보게 되었다.

테스트를 위한 방법으로는 두가지 방법이 있었다.

  1. Validator을 주입받아 체크하는 방법
  • javax.validation.Validator 인터페이스를 사용하여 객체의 유효성을 직접 검사
  • 컨트롤러나 다른 레이어와의 상호작용 없이 순수하게 도메인 모델의 유효성 검증에 집중
  1. Controller테스트 시에 MockMvc를 이용해 호출하여 테스트하는 방법
  • MockMvc는 Spring MVC의 동작을 모의하여 컨트롤러 레벨에서의 HTTP 요청과 응답을 테스트

1. Validator을 주입받아 체크하는 방법

테스트 코드에서 직접 validator을 주입받아 실행하여 체크한다.

class PostRegistDTOTest {

    private Validator validator;

    @BeforeEach
    void setUp() {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    @Test
    @DisplayName("validation 실패 테스트 Title 200자 이상")
    void validTest_WhenTileIsMoreThan200() {
        // given
        PostRegistDTO postRegistDTO = PostRegistDTO.builder().title(String.join("", Collections.nCopies(201, "T"))).build();

        // when
        Set<ConstraintViolation<PostRegistDTO>> violations = validator.validate(postRegistDTO);
        Iterator<ConstraintViolation<PostRegistDTO>> iterator = violations.iterator();
        List<String> messages = new ArrayList<>();

        while (iterator.hasNext()) {
            ConstraintViolation<PostRegistDTO> next = iterator.next();
            messages.add(next.getMessage());
        }

        // then
        assertThat(messages).contains("Title must be up to 200 characters.");
    }

    @Test
    @DisplayName("validation 실패 테스트 Content 1000자 이상")
    void validTest_WhenContentIsMoreThan1000() {
        // given
        PostRegistDTO postRegistDTO = PostRegistDTO.builder().title("Content Fail Test").content(String.join("", Collections.nCopies(1001, "T"))).build();

        // when
        Set<ConstraintViolation<PostRegistDTO>> violations = validator.validate(postRegistDTO);
        Iterator<ConstraintViolation<PostRegistDTO>> iterator = violations.iterator();
        List<String> messages = new ArrayList<>();

        while (iterator.hasNext()) {
            ConstraintViolation<PostRegistDTO> next = iterator.next();
            messages.add(next.getMessage());
        }

        // then
        assertThat(messages).contains("Content must be up to 1000 characters.");
    }
}

2. Controller테스트 시에 MockMvc를 이용해 호출하여 테스트하는 방법

MockMvc로 테스트를 진행한다

해당 테스트로 진행하면 HttpStatus와 에러메세지까지 확인할 수 있었다.

@SpringBootTest
@AutoConfigureMockMvc
class PostControllerTest {

    @Autowired
    MockMvc mockMvc;

    // Object to json and json to Object
    private ObjectMapper mapper = new ObjectMapper();

    @MockBean
    PostService postService;

    // Check whether the API sends the correct response
    @Test
    @DisplayName("insertPost validation 실패 테스트 Title 200자 이상")
    void insertPost_WhenTileIsMoreThan200() throws Exception {
        // given
        PostRegistDTO postRegistDTO = PostRegistDTO.builder()
                .title(String.join("", Collections.nCopies(201, "T")))
                .content("test")
                .build();

        Gson gson = new Gson();
        String content = gson.toJson(postRegistDTO);

        // when
        // then
        mockMvc.perform(post("/api/posts")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(content))
                .andExpect(status().isBadRequest()) // HTTP 상태 코드 검증
                .andExpect(jsonPath("$.message").value("Title must be up to 200 characters."));
        ;
    }

결과 : 객체와 Valid를 테스트하고 싶다면 Validator을 주입 받아 테스트하고 Http와 같이 테스트하고 싶다면 MockMvc를 이용하여 직접 호출하여 테스트하면 될 것 같다.

profile
안녕하세요

0개의 댓글