Programming/Spring

Spring Test Code 관련 - (MockMvc 등... 여러가지)

잇(IT) 2023. 11. 19. 16:53
- MockMvc
- MockMvc

 

1. Spring MVC 컨트롤러를 테스트하기 위해 사용된다. 이를 통해 웹 애플리케이션의 HTTP 요청과 응답을 시뮬레이션하고 테스트하는 것이 가능하다.

 

- @AutoConfigureMockMvc

 

1. Mock 객체를 자동 주입하기 위해 사용한다.

@SpringBootTest
@AutoConfigureMockMvc
public class MyControllerTest {

    @Autowired
    private MockMvc mockMvc;

    // 테스트 코드 작성
}

 

2.  위와 같이 MockMvc를 주입 받아 테스트 코드를 작성 할 수 있다.

 

- ObjectMapper

 

1. JSON 데이터와 Java 객체 간의 변환을 수행하는 데 사용되는 라이브러리다.

@Test
    @DisplayName("글 작성 요청시 Hello World를 출력한다.")
    void test() throws Exception {

        PostCreate request = PostCreate.builder()
                .title("제목입니다.")
                .content("내용입니다.")
                .build();

        String json = objectMapper.writeValueAsString(request);

 

2. 위와 같이 엔티티에 해당되는 request 객체를 objectMapper.writeValueAsString(request)처럼 작성하면, String 문자열 형태의 json 형식으로 변환해준다.

 2.1. json 형식으로 변환하는 이유는 HTTP를 통해 데이터를 전달 할 때 String 값을 전달해야 하기 때문이다.

 

- mockMvc.perform

 

1. perform은 HTTP 요청을 수행하고 컨트롤러를 테스트하기 위한 메서드다. 특정 HTTP 요청을 시뮬레이션하고 컨트롤러에 대한 요청을 실행한다.

@Test
    @DisplayName("글 작성 요청시 Hello World를 출력한다.")
    void test() throws Exception {
    
        PostCreate request = PostCreate.builder()
                .title("제목입니다.")
                .content("내용입니다.")
                .build();

        String json = objectMapper.writeValueAsString(request);

        //expected
        mockMvc.perform(MockMvcRequestBuilders.post("/posts")
                                .contentType(APPLICATION_JSON)
                                .content(json)
                )
                .andExpect(status().isOk())
                .andDo(print());
    }

 

2. MockMvcRequestBuilders는 다양한 유형의 HTTP 요청을 생성하고 설정하는데 사용된다.

 2.1. MockMvcRequestBuilders는 get, post, put, delete, patch, options 요청을 메서드로 생성하여 사용할 수 있다.

3. contentType, content와 같은 값들은 헤더에 포함된 정보로서, 아래와 같은 헤더 정보들을 생성하여 전달 할 수 있다.

 

4. 위 코드의 경우 contentType(APPLICATION_JSON) : HTTP 요청의 본문(body) 데이터가 어떤 형식의 데이터인지를 나타낸다 content의 경우 JSON 타입의 데이터를 직접 파라미터로 넘긴다. json은 엔티티를 objectMapper를 통해 String 타입의 json형태로 변경한 값에 해당한다.

5. andExpect() : HTTP 응답을 검증하는 데 사용된다. status()는 HTTP 응답의 상태 코드를 검증하는데 사용되는 메서드이다. isOk()는 HTTP 상태 코드가 200 (OK)인지를 검증한다. 이외에도 HTTP 응답의 상태코드를 원하는 코드를 입력 할 수 있다.

6. andDo() : 추가적인 동작을 수행하는데 사용된다. 위 코드에서 사용된 print()는 요청과 응답을 콘솔에 출력하여 디버깅 및 테스트 결과 확인을 도와준다.


- jsonPath

 

1. JsonPath는 JSON 데이터 구조에서 특정 요소를 선택하고 쿼리하는 데 사용된다.

mockMvc.perform(MockMvcRequestBuilders.post("/posts")
                                .contentType(APPLICATION_JSON)
//                {"title": ""} 검증이 정상적으로 되었다.
//                                .content("{\"title\": \"\", \"content\": \"내용입니다.\"}")
                                .content(json)
//                {"title": null}일 때
                )
//                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(status().isBadRequest())
//                .andExpect(MockMvcResultMatchers.content().string("Hello World"))
//                json 검증 방법에 좋은 것
                .andExpect(jsonPath("$.code").value("400"))
                .andExpect(jsonPath("$.message").value("잘못된 요청입니다."))
                .andExpect(jsonPath("$.validation.title").value("title을 입력해주세요"))
                .andDo(print());
    }

 

2. andExpect를 통해 요청에 대한 응답을 검증 할 수 있고, jsonPath를 이용하여 전달 받은 JSON 데이터를 key, value 형식으로 검증 받을 수 있다.

.andExpect(jsonPath("$.code").value("400"))
.andExpect(jsonPath("$.message").value("잘못된 요청입니다."))
.andExpect(jsonPath("$.validation.title").value("title을 입력해주세요"))

 

3. 위 코드를 보게 되면 요청에 대한 JSON 형식으로 응답을 받게 되는데 아래와 같이 JSON 형식으로 POST 요청을 보내게 되면 body를 통해 응답 결과를 전달 받을 수 있고 전달 받은 값을 $를 통해 key 값을 .value를 통해 value값을 검증 할 수 있다.

Postman을 사용한 화면


- header
mockMvc.perform(MockMvcRequestBuilders.post("/posts")
                        .header("authorization", "bis")
                                .contentType(APPLICATION_JSON)
//                                .content("{\"title\": \"제목입니다.\", \"content\": \"내용입니다.\"}")
                                .content(json)
                )
                .andExpect(status().isOk())
                .andDo(print());

 

1. 요청 헤더를 사용하는 경우도 존재한다. 인증 토큰 또는 사용자 인증 정보를 서버로 전달하기 위해 사용된다.

(토큰 관련 인증 내용은 추후에 다룰 것이다.)

2. header에 authorization 정보를 전달함으로서 해당 요청이 인증된 요청인지 아닌지 검증 후 인증된 요청인 경우 그에 해당하는 응답을 전달하고, 인증되지 않은 header일 경우 그에 해당하는 검증 실패 응답을 전달할 것이다.


- 페이징 요청

 

@Test
    @DisplayName("글 여러개 조회")
    void test5() throws Exception {
        //given
        List<Post> requestPosts = IntStream.range(1, 31)
                .mapToObj(i -> Post.builder()
                        .title("Title : " + i)
                        .content("Content : " + i)
                        .build())
                .collect(Collectors.toList());
        postRepository.saveAll(requestPosts);
        //expected
        mockMvc.perform(MockMvcRequestBuilders.get("/posts?page=1&size=10")
                        .contentType(APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.length()", Matchers.is(10)))
                .andExpect(jsonPath("$[0].id").value(requestPosts.get(requestPosts.size() - 1).getId()))
                .andExpect(jsonPath("$[0].title").value("Title : 30"))
                .andExpect(jsonPath("$[0].content").value("Content : 30"))
                .andDo(print());
    }

 

1. 페이징 요청도 일반 요청과 마찬가지로 요청 파라미터에 페이징 정보를 넘김으로서 테스트 할 수 있다.

2. $ 기호를 통해 JSON 데이터의 루트를 확인 할 수 있다. .length()를 통해 JSON 형식의 응답 데이터의 길이를 확인 할수 있고, $[0] 형식을 통해 JSON 데이터의 0번째 데이터를 확인 하는 등 여러가지 검증 작업이 가능하다.


- 그 외 여러가지

 

mockMvc.perform(MockMvcRequestBuilders.get("/posts/{postId}", post.getId())

 

1. 요청 경로에 변수가 들어갈 경우 위와 같이 , 기호 뒤에 해당 변수에 들어갈 값을 지정하여 넣을 수 있다.

728x90