AssertJ는 테스트 라이브러리이다.
메소드 체이닝을 지원하기 때문에 좀 더 깔끔하고 읽기 쉬운 테스트 코드 작성 가능(가독성이 좋음)
개발자가 테스트를 하면서 필요하다고 상상할 수 있는 거의 모든 메소드를 제공
의존성
spring-boot-starter-test
에 기본적으로 포함되어있다. spring-boot-starter-test
를 사용하지 않고 추가하는 경우에는 다음과 같이 추가할 수 있다.
Gradle
Copy testCompile 'org.assertj:assertj-core:3.21.0'
Maven
Copy <dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.21.0</version>
<scope>test</scope>
</dependency>
테스트 코드 작성 시작하기
Assertions.assertThat()
모든 테스트 코드는 assertThat()
메서드에서 시작한다.
Copy assertThat(테스트 타겟)
.method1()
.method2()
.method3();
테스트 실패 메세지
테스트 실패시 나타낼 메세지를 .as()
로 표현할 수 있다.
Copy @Test
void asExample() {
String blank = " ";
assertThat(StringUtils.hasText(blank))
.as("check '%s' is null", blank)
.isTrue();
}
다음과 같이 작성해두면 테스트 실패시 콘솔창에 에러메세지가 다음과 같이 출력된다.
Copy [check ' ' is null]
Expecting value to be true but was false
org.opentest4j.AssertionFailedError: [check ' ' is null]
다음과 같이 검증문 뒤에 작성할 경우 호출되지 않는 것을 볼 수 있다.
Copy @Test
void asExample() {
String blank = " ";
assertThat(StringUtils.hasText(blank))
.isTrue()
.as("check '%s' is null", blank);
}
Copy Expecting value to be true but was false
org.opentest4j.AssertionFailedError:
Expecting value to be true but was false
Collection 필터링
.filteredOn()
.filteredOn()
으로 테스트할 데이터들을 필터링 할 수 있다.
Copy @Test
void test() {
EnumSet<DayOfWeek> days = EnumSet.allOf(DayOfWeek.class);
assertThat(days)
.filteredOn(d -> d.getValue() > 4)
.containsOnly(DayOfWeek.FRIDAY, DayOfWeek.SATURDAY, DayOfWeek.SUNDAY);
}
이때 not
, in
, notIn
에 대한 객체 프로퍼티를 검증할 수 도 있다.
Copy List<Human> list = new ArrayList<>();
list.add(new Human("faker", 26));
list.add(new Human("bang", 26));
list.add(new Human("wolf", 26));
list.add(new Human("keria", 20));
assertThat(list)
.filteredOn("age", not(26))
.containsOnly(list.get(3));
기존의 클래스의 특정 데이터를 비교하기 위해서는 별도 리스트를 만들어 다음과 같이 테스트를 진행해야했다.
Copy @Test
void no_extracting() throws Exception{
List<String> names = new ArrayList<>();
for (T1 member : members) {
names.add(member.getName());
}
assertThat(names).containsOnly("faker", "bang", "wolf", "keria");
}
하지만 assertj에서 extracting
을 지원해주면서 필요한 데이터만 추출해 테스트가 가능해졌다.
Copy @Test
void extracting() {
List<T1> members = new ArrayList<>();
members.add(new T1("faker", 26));
members.add(new T1("bang", 26));
members.add(new T1("wolf", 26));
members.add(new T1("keria", 20));
assertThat(members)
.extracting("name")
.contains("faker", "bang", "wolf", "keria");
assertThat(members)
.extracting("name", "age")
.contains(tuple("faker", 26),
tuple("bang", 26),
tuple("wolf", 26),
tuple("keria", 20));
}
추출할 데이터가 한개라면 타입 지정이 가능하며, 여러개인 경우에는 assertj에서 지원해주는 tuple()
로 테스트할 수 있다.
SoftAssertions
Assertions.assertThat()
은 테스트가 한개라도 실패하면 해당 테스트는 중지된다.
SoftAssertions
을 이용하면 모든 assertThat을 실행하고 해당 실패 내역을 확인할 수 있다.
Copy @Test
void test() {
String str = "test";
SoftAssertions.assertSoftly(softAssertions -> {
softAssertions.assertThat(StringUtils.hasText(str))
.as("check '%s' is not null", str)
.isFalse();
softAssertions.assertThat(StringUtils.hasLength(str))
.as("check '%s' is not null", str)
.isTrue();
});
}
Copy Multiple Failures (1 failure)
-- failure 1 --
[check 'test' is not null]
Expecting value to be false but was true
at SoftAssertionTest.lambda$test$0(SoftAssertionTest.java:15)
org.assertj.core.error.AssertJMultipleFailuresError:
Multiple Failures (1 failure)
-- failure 1 --
참고