equals를 정의하지 않고도 객체의 일부 속성만 비교하는 테스트를 작성할 수 있다!?!?🤸‍♂️

sojukang·2022년 5월 9일
0

결론

assertjusingRecursiveComparison 를 사용하면 원하는 값들로만 비교하여 isEqualTo를 사용할 수 있다.

객체의 equals와 hashcode를 재정의하지 않아도 isEqualTo 비교가 가능하다고!?!?🤸‍♂️🤸‍♂️

체스 미션에서 Dao 테스트를 작성할 때 일이다. id 값이 없는 Line을 생성하여 Dao의 save 메서드를 호출하여 받은 Auto increment된 id가 포함된 Line객체가 같은 필드를 갖고 있는지 검증하는 테스트를 작성하려 하였다. Line 객체는 id, name, color 필드를 가지고 있다.
코드는 다음과 같았다.

@Test
@DisplayName("Line 을 저장한다.")
void save() {
    //given
    Line line = new Line("7호선", "khaki");

    //when
    Line actual = lineDao.save(line);

    //then
    assertThat(actual.getName()).isEqualTo(line.getName());
    assertThat(actual.getColor()).isEqualTo(line.getColor());
 }

아~ 불편하다. 그러면 필드가 3개면 3개의 assert문, N개면 N개의 속성을 비교해야할까? 자. 그러면 equals를 재정의 하면 어떨까?

Entity의 equals와 hashcode를 재정의해도 될까?

Entity는 담고 있는 값만 같다면 같은 객체로 간주할 수 있는(동등) VO(Value Object)와 다르다. 식별성을 가지고 객체 주기 동안 유지되는 연속성이 핵심이다. 우리의 코드에서는 id 필드가 다르더라도 테스트를 위해 name, color의 동등성을 비교하기 위해 equals와 hashcode를 재정의할 경우 엔티티의 연속성을 위반하게된다.

그러면 테스트에서 메소드를 분리해보자!

private void hasSameNameAndColor(Line actual, Line expected) {
    return actual.getName().equals(expected.getName()) && actual.getColor().equals(expected.getColor());

하... assertThat 코드가 깔끔해지기는 했어도 필드가 늘어나면 메소드가 지저분해지는 건 똑같다. 우리에게 구원책은 없을까???😭😭😭

assertjusingRecursiveComparison 를 사용하자!!!

다행히 우리의 assertj는 은총을 가지고 계신다. usingRecursiveComparison 메서드를 사용하면 재귀적으로 객체의 필드를 순회하며 동등성 비교를 해준다. 따라서 우리는 객체의 필드가 변경될 때마다 테스트를 수정할 필요가 없어진다!!! 이 얼마나 기적같은 일인가!!!
百聞不如一見! 위의 메서드와 같은 기능을 하는 코드는 아래와 같다.

private void checkHasSameNameAndColor(Line actual, Line expected) {
        assertThat(actual).usingRecursiveComparison()
            .ignoringFields("id") // 비교하지 않을 필드를 지정할 수 있다. 
            // .ignoringActualNullField Null인 필드를 비교하지 않을 수 있다.
            .isEqualTo(expected);
    }

이 얼마나 신성한 코드인가! 우리는 자유롭게 손쉽게 비교하지 않을 필드를 지정할 수도, Null이 있는 값은 비교하지 않을 수도 있다!!!
이로써 우리의 테스트 코드는 Line의 변경에도 유연하게 대응할 수 있는 구조가 되었다. 기쁘도다 기쁘도다!!!🤸‍♂️🤸‍♂️🌟

바퀴를 새로 발명하지 말자

우리의 assertj는 테스트를 쉽게 하기 위한 여러가지 기능들을 제공하고 있다. 하... 내가 꼭 이런 테스트 코드를 짜야 해...? 라고 고민하는 판다같은 사람이라면 assertj가 제공하는 기능들을 탐색해보자. 그대에게 은총이 내릴지어니.

참고

우리의 사랑 코니
에릭 에반스, 도메인 주도 설계, 위키북스

profile
기계공학과 개발어린이

0개의 댓글