본문 바로가기
Spring/Test

flatExtracting 활용해서 내부 리스트 내용 검증하기

by 흑시바 2023. 12. 3.

필자는 List 내용을 검증할 때 보통 extracting과 contains 관련 메서드를 활용을 하는데, 가끔 List 내부에 있는 List까지 검증해야 하는 경우가 있다. 이런 경우 일반적인 extracting 메서드를 사용하면 검증에 실패한다.

 

    @Builder
    @Getter
    public static class ShibaDto {
        private Long id;
        private String name;
        private List<Element> elementList;
    }

    @Builder
    @Getter
    public static class Element {
        private Long id;
        private Long age;
        private List<InnerElement> innerElementList;
    }

    @Builder
    @Getter
    public static class InnerElement {

        private Long id;
        private String name;
    }

 

그러면 extracting을 활용해서 Element -> InnerElement 내용에 어떻게 접근할 수 있을까? 해당 객체를 가지고 간단한 테스트 코드를 작성해 보았다.

 

    @Test
    void flatExtractingTest() {

        InnerElement innerElement1 = InnerElement.builder()
                .id(1L)
                .name("blackShiba")
                .build();

        InnerElement innerElement2 = InnerElement.builder()
                .id(2L)
                .name("whiteShiba")
                .build();

        Element element1 = Element.builder()
                .id(1L)
                .age(10L)
                .innerElementList(Arrays.asList(innerElement1, innerElement2))
                .build();

        ShibaDto shibaDto = ShibaDto.builder()
                .id(1L)
                .name("ShibaHolic")
                .elementList(Arrays.asList(element1))
                .build();

        assertThat(shibaDto.getElementList())
                .extracting("innerElementList")
                .extracting("id", "name")
                .contains(tuple(1L, "blackShiba"), tuple(2L, "whiteShiba"));
    }

 

우선 extracting을 2번 사용해서 innerElementList에 접근해서 검증을 시도해 본다.

 

예외가 발생하는데, 이유는 결과가 ArrayList 이므로, id라는 필드를 찾을 수 없기 때문이라고 한다.

 

innerElementList에 접근해서 순회하면서 id, name을 조회할 줄 알았지만 예상과 다르게 extracting의 결과로 ArrayList를 내보낸다.

 

그러면 이쯤에서 Java의 stream을 주로 사용했던 사람들은 목록을 Flat 하게 만들어서 변환하는 flatMap()처럼 flat과 같은 기능이 있지 않을까?라는 생각이 들 수도 있다.

 

실제로 List 처리에 대해서, assertJ는 flatExtracting 메서드를 지원하고 있다.

 

flatExtracting은 Iterable 요소에서 속성을 추출하기 위해 Java 8의 람다를 활용하는 특수 유틸리티 메서드이다.

 

        assertThat(shibaDto.getElementList())
                .flatExtracting("innerElementList")
                .extracting("id", "name")
                .contains(tuple(1L, "blackShiba"), tuple(2L, "whiteShiba"));

 

extracting -> flatExtracting으로 변경하면, 내부 값에 접근하게 되고 정상적으로 테스트가 성공하게 된다.

 

 

댓글