logo

객체 필드 값을 비교하여 테스트 결과 검증할 때..

객체타입을 정의합니다.
그리고 때로는 주소 가아닌, 같은 값을 가지고 있는지 테스트 할 때가 필요합니다.

final Parent podoA = new Parent("podo", 27);
final Parent podoB = new Parent("podo", 27);

assert podoA == podoB // false
assert podoA.getName() ==  podoB.getName(); //true
assert podoA.getAge() ==  podoB.getAge(); //true

<br>

getter()를 쓰기 보단..

그럼 값을 검증하기 위해 getter()를 사용하여 검증하는것도 방법입니다.
아니면 객체에 equals(), hashcode()를 정의해 equals() 하나로 해결하는것도 방법입니다.

그리고 다음 방법이 있습니다 (!!)

<br>

다음 코드를 이용하면 좀 더 편리합니다.

서론입니다.

객체타입을 정의했습니다.

@RequiredArgsConstructor
public class Parent{
    private final String name;
    private final int age;
}

<br>

그리고 AssertJ 를 이용합니다.
spring-boot-start-test 라이브러리를 의존하면, AssertJ를 포함하고있습니다.
https://pjh3749.tistory.com/241

<br>

1번. 모든 필드값 비교하기

public void test(){
    final Parent podoA = new Parent("podo", 27);
    final Parent podoCloneA = new Parent("podo", 27);
    
    assertThat(podoA).isEqualToComparingFieldByField(podoCloneA); //true
}

<br>

2번. 특정 필드값 비교하기

@Test
public void test(){
    final Parent podoA = new Parent("podo", 1);
    final Parent podoNameCloneA = new Parent("podo", 2);

    assertThat(podoA).isEqualToComparingOnlyGivenFields(podoNameCloneA, "name"); // 이름만비교
}

<br>

3번. 특정 필드값 무시하며 비교하기

@Test
public void test(){
    final Parent podoA = new Parent("podo", 1);
    final Parent podoNameCloneA = new Parent("podo", 2);

    assertThat(podoA).isEqualToIgnoringGivenFields(podoNameCloneA, "age"); // 나이는 무시
}

<br>

4번. Collections 모든 필드값으로 비교하기

@Test
public void test(){
    final Parent podoA = new Parent("podoA", 27);
    final Parent podoCloneA = new Parent("podoA", 27);
    final Parent podoB = new Parent("podoB", 1);
    final Parent podoCloneB = new Parent("podoB", 1);

    assertThat(Arrays.asList(podoA, podoB))
            .usingFieldByFieldElementComparator()
            .containsExactlyInAnyOrder(podoCloneA, podoCloneB);

}

컬렉션의 순서까지 일치하고싶다면
containsExactly()를 사용합니다.

<br>

5번. Collection에서 특정 필드값으로 비교하기

@Test
public void test(){
    final Parent podoA = new Parent("podoA", 27);
    final Parent podoNameCloneA = new Parent("podoA", 0);
    final Parent podoB = new Parent("podoB", 1);
    final Parent podoNameCloneB = new Parent("podoB", 0);

    assertThat(Arrays.asList(podoA, podoB))
            .usingElementComparatorOnFields("name") // 이름만 비교
            .containsExactlyInAnyOrder(podoNameCloneA, podoNameCloneB);

}

<br>

6번. Collection에서 특정 필드값 무시하며 비교하기

@Test
public void test(){
    final Parent podoA = new Parent("podoA", 27);
    final Parent podoNameCloneA = new Parent("podoA", 0);
    final Parent podoB = new Parent("podoB", 1);
    final Parent podoNameCloneB = new Parent("podoB", 0);

    assertThat(Arrays.asList(podoA, podoB))
            .usingElementComparatorIgnoringFields("age") // 나이는 무시하기
            .containsExactlyInAnyOrder(podoNameCloneA, podoNameCloneB);

}

<br>

부모에게 자식이 생겼습니다.

위의 예제는 객체안에 만 있을때는 가능합니다.

다음 객체를 정의했습니다.

@RequiredArgsConstructor
public class Parent{
    private final String name;
    private final int age;
    private final Child child;
}

@RequiredArgsConstructor
public class Child{
    private final String childName;
    private final int childAge;
}

<br>

하지만 객체 안에 객체를 정의했을경우에는, 내부 객체는 주소값을 비교하기 때문에 false를 반환합니다.

@Test
public void test(){
    final Parent podoA = new Parent("podo", 27, new Child("podoBaby", 1));
    final Parent podoCloneA = new Parent("podo", 27, new Child("podoBaby", 1));

    assertThat(podoA).isEqualToComparingFieldByField(podoCloneA); /// 자식이 달라,, false!!!
}

그리고 한발더 나아 갑니다.(!)

<br>

7번. 자식까지 모든값 비교하기

@Test
public void test(){
    final Parent podoA = new Parent("podo", 27, new Child("podoBaby", 1));
    final Parent podoCloneA = new Parent("podo", 27, new Child("podoBaby", 1));

    assertThat(podoA).usingRecursiveComparison().isEqualTo(podoCloneA);
}

<br>

8번. 자식까지 특정 필드 무시하며 비교하기

.을 사용해서 내부객체에 대해 접근합니다.

@Test
public void test(){
    final Parent podoA = new Parent("podo", 27, new Child("podoBaby", 1));
    final Parent podoCloneA = new Parent("podo2222", 27, new Child("podoBaby22222", 1));

    assertThat(podoA)
            .usingRecursiveComparison()
            .ignoringFields("name", "child.childName") //부모의 이름과, 자식의 이름은 무시
            .isEqualTo(podoCloneA);
}

<br>

9번, Collection에서 자식까지 모든 필드 비교하기

@Test
void test(){
    final Parent podoA = new Parent("podoA", 27, new Child("podoBabyA", 1));
    final Parent podoCloneA = new Parent("podoA", 27, new Child("podoBabyA", 1));
    final Parent podoB = new Parent("podoB", 21, new Child("podoBabyB", 2));
    final Parent podoCloneB = new Parent("podoB", 21, new Child("podoBabyB", 2));

    assertThat(Arrays.asList(podoA, podoB))
            .usingRecursiveFieldByFieldElementComparator()
            .containsExactly(podoCloneA, podoCloneB);
}

<br>

10번, 그밖..

그밖에 equals() 무시하기,
특정 field에 커스텀 compator() 정의하기
특정 type에 커스텀 compator() 정의하기 등
무시무시하게 다양한 조합으로 사용할 수 있습니다.

CommentCount 0
이전 댓글 보기
등록
TOP