본문 바로가기
📚Framework & Library/JUnit

[Junit] TypeReference, JsonPath - Json 다루기 (feat. ObjectMapper)

by inbeom 2023. 11. 17.
728x90
Junit을 사용하여 Integration Test Case 작성 중 데이터 검증로직을 구현할 때 유용하게 사용할 수 있다.

 

 

TypeReference란? 

  • TypeReference는 Jackson 라이브러리에서 제공하는 클래스로, 제네릭 타입을 사용하는 경우에 JSON 데이터를 해당 제네릭 타입으로 역직렬화할 때 유용하다.
  • Jackson은 제네릭 타입 정보를 유지할 수 없기 때문에 이러한 경우에 TypeReference를 사용하여 타입 정보를 보존한다.

 

Example >

List<Person> list = new ObjectMapper().readValue(responseContent, new TypeReference<List<Person>>(){});

    @Test //Todo. User 리스트 조회 테스트
    @Transactional
    public void userListTest() throws Exception {
        // given
        // Parameter, Body 등 API 요청 시 보낼 데이터 세팅
        // when
        result = mockMvc.perform(
                        get("/api/user/user-list")
                                .session(session))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print())
                .andReturn();
        // then
        String responseContent = result.getResponse().getContentAsString();
        // Person person = nw ObjectMapper().readValue(responseContent, Person.class);
        List<Person> list = new ObjectMapper().readValue(responseContent, new TypeReference<List<Person>>(){});
        assertThat(list).isNotNull().isInstanceOf(ArrayList.class);
        assertThat(list.get(0).getName()).isEqualTo("aa");
    }
반환값이 단일 클래스 객체이면 '클래스명.class' 로 역직렬화 할 수 있지만 List<Person> 이렇게 상위 타입에 묶있으면 TypeReference를 이용하여 타입정보를 보존해 역직렬화 할 수 있다.

 


 

JsonPath란?

 

  • JsonPath는 JSON 문서에서 데이터를 쿼리하고 추출하는 데 사용되는 경로 표현 언어이다. XML의 XPath와 유사한 개념을 JSON에 적용한 것으로, JSON 데이터 구조에서 특정 값을 선택하거나 쿼리하기 위해 사용한다.
  • 다양한 프로그래밍 언어에서 지원되며, 여러 라이브러리에서도 사용할 수 있다. 자바에서는 Jayway JsonPath나 com.jayway.jsonpath.JsonPath와 같은 라이브러리를 사용할 수 있다.

 

Example >

assertThat(Optional.ofNullable(JsonPath.read(responseContent, "$.userInfo.id"))).isEqualTo(Optional.ofNullable(JsonPath.read(returnValue, "$.userInfo.id")));

    @Test //Todo. 보고서 상세정보 (Html) 조회 테스트
    @Transactional
    public void getReportDetailHtmlResultTest() throws Exception {
        // given
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("report_num", "5z23hgh4223fewfe");
        map.add("start_date", "2023-12-29");
        // when
        result = mockMvc.perform(
                        get("/api/report/detail/html-result")
                                .params(map)
                                .session(session))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print())
                .andReturn();
        // then
        String responseContent = result.getResponse().getContentAsString();
        String returnValue = "{\"userInfo\":{\"id\":\"a1243\",\"name\":\"siri\",\"age\":\"29\"}}";

        assertThat(Optional.ofNullable(JsonPath.read(responseContent, "$.userInfo.id"))).isEqualTo(Optional.ofNullable(JsonPath.read(returnValue, "$.userInfo.id")));
        assertThat(Optional.ofNullable(JsonPath.read(responseContent, "$.userInfo.name"))).isEqualTo(Optional.ofNullable(JsonPath.read(returnValue, "$.userInfo.name")));
        assertThat(Optional.ofNullable(JsonPath.read(responseContent, "$.userInfo.age"))).isEqualTo(Optional.ofNullable(JsonPath.read(returnValue, "$.userInfo.age")));
    }

 

Json데이터 값이 문자열 형태로 반환된 경우 JsonPath.read(문자열, 경로)  read함수를 사용하여 원하는 경로의 Value를 쉽게 뽑아올 수 있다.

 

 

JsonPath 표현식:

  • $는 루트를 나타낸다.
  • store는 루트 객체의 store 속성을 나타낸다.
  • book은 store의 book 배열을 나타낸다.
  • [*]는 배열의 모든 요소를 선택한다.
  • title은 각 책 객체의 title 속성을 나타낸다.

 

 

ObjectMapper:
Jackson 라이브러리에서 제공하는 클래스로, Java 객체와 JSON 데이터 간의 변환을 담당한다.
주로 Java 객체를 JSON 문자열로 직렬화하거나 JSON 문자열을 Java 객체로 역직렬화하는 데 사용됩니다.

 

 

 

728x90