assertj
의 usingRecursiveComparison
를 사용하면 원하는 값들로만 비교하여 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
는 담고 있는 값만 같다면 같은 객체로 간주할 수 있는(동등) 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
코드가 깔끔해지기는 했어도 필드가 늘어나면 메소드가 지저분해지는 건 똑같다. 우리에게 구원책은 없을까???😭😭😭
assertj
의 usingRecursiveComparison
를 사용하자!!!다행히 우리의 assertj
는 은총을 가지고 계신다. usingRecursiveComparison
메서드를 사용하면 재귀적으로 객체의 필드를 순회하며 동등성 비교를 해준다. 따라서 우리는 객체의 필드가 변경될 때마다 테스트를 수정할 필요가 없어진다!!! 이 얼마나 기적같은 일인가!!!
百聞不如一見!
위의 메서드와 같은 기능을 하는 코드는 아래와 같다.
private void checkHasSameNameAndColor(Line actual, Line expected) {
assertThat(actual).usingRecursiveComparison()
.ignoringFields("id") // 비교하지 않을 필드를 지정할 수 있다.
// .ignoringActualNullField Null인 필드를 비교하지 않을 수 있다.
.isEqualTo(expected);
}
이 얼마나 신성한 코드인가! 우리는 자유롭게 손쉽게 비교하지 않을 필드를 지정할 수도, Null이 있는 값은 비교하지 않을 수도 있다!!!
이로써 우리의 테스트 코드는 Line의 변경에도 유연하게 대응할 수 있는 구조가 되었다. 기쁘도다 기쁘도다!!!🤸♂️🤸♂️🌟
우리의 assertj
는 테스트를 쉽게 하기 위한 여러가지 기능들을 제공하고 있다. 하... 내가 꼭 이런 테스트 코드를 짜야 해...?
라고 고민하는 판다
같은 사람이라면 assertj
가 제공하는 기능들을 탐색해보자. 그대에게 은총이 내릴지어니.
우리의 사랑 코니
에릭 에반스, 도메인 주도 설계, 위키북스