자바에서 테스트 코드 작성시 제공하는
Assertj메소드는 사진과 같이 두 가지 입니다.
- 두 가지의
Assertj라이브리러를 통해 실행 로직을 "검증" 해볼수 있습니다.- 두 가지의 경우의 차이점과 왜
org.assertj.core.api.Assertions.assertThat()가 권장 되는지 작성해 보겠습니다.
(물론org.junit.jupiter.api를 쓰지 말라는 말은 아닙니다.)
제가 작성한 테스트 코드 입니다.
JUnit 5환경에서Assertions.assertThat()을 사용해Json으로 파싱한 데이터의 값을 검증 하였습니다.
- 저는 테스트 코드를 작성하면서 습관적으로
Assertions.assertThat()을 사용했지만, 그 이유를 몰랐으며 궁금증이 생겼습니다.
org.assertj.core.api.Assertions사용시 작성 방식입니다.
최종적으로 검증 코드는 아래와 같이 equal 한지 notEqual 한지 작성할수 있습니다.
@Test
void 테스트() {
String name = "신재원";
org.assertj.core.api.Assertions.assertThat(name).isEqualTo("신재원");
org.assertj.core.api.Assertions.assertThat(name).isNotEqualTo("홍길동");
}
org.junit.jupiter.api.Assertions사용시 작성 방식 입니다.
최종적으로 검증 코드는 아래와 같이 괄호 한 묶음에서 값을 비교할수 있습니다.
@Test
void 테스트() {
String name = "신재원";
org.junit.jupiter.api.Assertions.assertEquals(name, "신재원");
}
이제 부터 설명을 작성하는것은 org~ 라이브러리 주소를 빼고 작성하겠습니다.
@Test
void 테스트() {
String name = "신재원";
// 1. assertj 사용
Assertions.assertThat(name).isEqualTo("신재원");
// 2. junit 사용
Assertions.assertEquals(name, "신재원");
}
assertj 사용 코드는 가독성과 표현성이 좋습니다. 이유로는 실제 값인 name 변수를 예상값인 신재원 과 검증 하는지 쉽게 유추 할수 있으며 왼쪽에서 오른쪽 으로 자연스럽게 읽히게 됩니다.
(테스트 단계를 체이닝 하여 표현력이 좋아 지게 됩니다)
하지만 junit 을 사용한 코드는 어느 값이 실제값이고, 어느값이 예상값인지 쉽게 유추 하기 어려울수 있습니다.
이와 같이 assertj 를 사용하면 가독성과 표현력이 좋아지게 됩니다.
@Test
void 테스트() {
List<String> names = List.of("신재원", "홍길동");
// true 값 반환 검증
Assertions.assertTrue(names.containsAll(List.of("신재원", "홍길동"))
&& names.size() == 2);
Assertions.assertTrue(names.containsAll(List.of("신재원", "홍길동")));
// 배열로 변환후 true 값 반환 검증
Assertions.assertArrayEquals(names.toArray(),
new String[]{"신재원", "홍길동"});
}
Junit 에서는 간단한 메소드만 제공해주기 때문에, 비교를 하기위해 다양한 조건을 추가해서 작성해줘야 합니다. @Test
void 테스트() {
List<String> names = List.of("신재원", "홍길동");
/*
true 값 반환 검증
containsExactlyInAnyOrder : names 컬렉션 객체에 데이터가
순서와 상관없이 값만 일치한지 확인
*/
Assertions.assertThat(names)
.containsExactlyInAnyOrder("신재원", "홍길동");
/*
containsExactly : names 컬렉션 객체에서 지정한 데이터의
순서와 값이 일치한지 확인
*/
Assertions.assertThat(names)
.containsExactly("신재원", "홍길동");
/*
contains : names 컬렉션 객체에서 지정한 데이터가 순서와 상관없이 존재하면 되고,
다른 원소를 더 추가해도 됩니다.
*/
Assertions.assertThat(names)
.contains("홍길동", "신재원");
}
assertj 에서는 다양한 메소드를 제공해주기 때문에, 다른 작업이 따로 필요 없으며, 가독성이 좋아지며 통일성이 생기게 됩니다.assertj는 정말 다양한 메소드들 제공하기 때문에, assertThat() 작성후 .을 찍어 자동완성 기능을 잘 활용하면 좋습니다.Assertj 에서는 메소드 체이닝 기능을 제공합니다.
메소드 체이닝이란 간단히 말하여, . 을 통해 Builder 패턴 처럼 사용한다는 것입니다.
@Test
void 테스트1() {
Assertions.assertThat("Hello jaewon")
.isNotBlank()
.contains("Hello")
.containsOnlyOnce("jaewon")
.startsWith("Hello");
}
@Test
void 테스트2() {
Assertions.assertThat(98)
.isPositive() // 양수인지 확인
.isGreaterThan(90)
.isNotEqualTo(99)
.isLessThan(100)
.isEqualTo(98);
}
이러한 3가지의 차이점을 적어서 정리하였지만, assertj 를 사용해야 이유는 정말로 많이 있습니다.
이제부터 assertj 를 사용해야 하는 이유와 방법에 대해 알았으니 테스트 코드 작성시 이유를 리마인드 하면 좋을것 같습니다.