[assertJ] 공식문서와 함께하는 assertJ 정리
2021-02-05 글
JUnit5으로 테스트 코드를 작성하면서 assertion을 주는 도구로 assertJ를 배웠다.
새로 깨닫게 된 것은 정리하며 익히자.
assertJ?
Java 테스트에서 유창하고 풍부한 assertions를 작성하는 데 사용되는
오픈 소스 커뮤니티 기반 라이브러리
지원
- Standard Java
- Java 8
- Guava
- Joda Time
- Neo4J and
- Swing components
Assertions 작성
Assertions.assertThat()에 object를 전달하면 assertion을 받을 수 있다.
Obejct Assertions
Obejct는 두 객체의 동일성이나 객체의 필드를 조사하기 위해 다양한 방법으로 비교할 수 있다.
Example
두 Dog의 객체인 fido와 fidoClone이 주어질 때
public class Dog {
private String name;
private Float weight;
// standard getters and setters
}
Dog fido = new Dog("Fido", 5.25);
Dog fidosClone = new Dog("Fido", 5.25);
assertThat
을 이용해 비교한다.
assertThat(fido).isEqualTo(fidosClone);
하지만 isEqualsTo()
가 객체의 참조를 비교하므로 fail이다.
내용을 비교하려면 isEqualToComparingFieldByFieldRecursively()
를 사용한다.
assertThat(fido).isEqualToComparingFieldByFieldRecursively(fidosClone);
✍️ 참고로 페어프로그래밍을 하면서 페어에게 들었는데 assertEquals
보다 assertThat
이 좀 더 직관적이기 때문에 가급적 assertThat()
을 사용하라고 알려줬다.
Boolean Assertions
- isTrue()
- isFalse()
assertThat("".isEmpty()).isTrue();
Iterable/Array Assertions
Iterable/Array에 특정 요소가 존재하는지 다양한 방법으로 알 수 있다.
여기서는 특정 요소가 포함되어 있는지 확인한다.
List<String> list = Arrays.asList("1", "2", "3");
assertThat(list).contains("1");
Example
list가 비어 있지 않은 경우
assertThat(list).isNotEmpty();
list가 주어진 문자로 시작하는 경우
assertThat(list).startsWith("1");
동일한 객체에 하나 이상의 assertion을 생성하려는 경우 체이닝을 통해 쉽게 결합할 수 있다.
assertThat(list)
.isNotEmpty()
.contains("1")
.doesNotContainNull()
.containsSequence("2", "3");
Character Assertions
Character에 대한 assertions는 비교 대상 문자가 유니코드 테이블에 있는지 확인하는
작업을 포함한다.
Example
문자가 'a'가 아니고 유니코드 테이블에 있는지, 'b'보다 크고 소문자인지 확인하는 assertion
assertThat(someCharacter)
.isNotEqualTo('a')
.inUnicode()
.isGreaterThanOrEqualTo('b')
.isLowerCase();
Class Assertions
해당 필드, 클래스 유형, annotations의 존재 등을 체크한다.
Example
해당 클래스가 Runnable인지 확인
assertThat(Runnable.class).isInterface();
한 클래스가 다른 클래스에 할당 가능한지 확인
assertThat(Exception.class).isAssignableFrom(NoSuchElementException.class);
File Assertions
지정된 File 인스턴스가 존재 하는지, 디렉토리 또는 파일인지,
특정 콘텐츠가 있는지, 읽을 수 있는지 또는 확장명이 있는지 확인한다.
Example
파일이 존재하고, 디렉토리가 아닌 파일이며, 읽고 쓸 수 있는지 확인
assertThat(someFile)
.exists()
.isFile()
.canRead()
.canWrite();
Double / Float / Integer Assertions
주어진 Offset 안에서 혹은 없는 숫자 값을 비교한다.
assertThat(5.1).isEqualTo(5, withPrecision(1d));
InputStream Assertions
- hasSameContentAs(InputStream expected)
assertThat(given).hasSameContentAs(expected);
Map Assertions
맵에 특정 항목, entry, key/value 값이 포함되어 있는지 확인한다.
Example
맵이 비어있지 않고 키 2를 포함하며, 키 10을 포함하지 않고 (2, "a")를 포함하는지 확인
assertThat(map)
.isNotEmpty()
.containsKey(2)
.doesNotContainKeys(10)
.contains(entry(2, "a"));
Throwable Assertions
예외 메시지, 스택 추적 검사, 예외가 이미 throw 되었는지 확인
Example
주어진 예외가 발생했는지 확인하고 "c"로 끝나는 메시지가 있는지 확인
assertThat(ex).hasNoCause().hasMessageEndingWith("c");
교육에서 이 Throwable Assertions로 예외를 발생시켰는지 확인했다.
assertThatThrownBy와 assertThatExceptionOfType 두 가지 방법으로 처리가 가능함을 깨달았다.
- assertThatThrownBy() : Java 8 exception assertion 표준 스타일
- assertThatExceptionOfType() : 예외 클래스 넣기
@Test
@DisplayName("특정 위치 문자 가져오기 has")
public void charGetFromString1() {
String name = "Fortune";
int index = 10;
assertThatThrownBy(() -> {
name.charAt(index);
}).isInstanceOf(IndexOutOfBoundsException.class)
.hasMessageContaining("%d", index);
}
@Test
@DisplayName("특정 위치 문자 가져오기 with")
public void charGetFromString2() {
String name = "Fortune";
int index = 10;
assertThatExceptionOfType(IndexOutOfBoundsException.class)
.isThrownBy(() -> {
name.charAt(index);
}).withMessageContaining("%d", index);
}
java8에서 더 유용하게
java7
assertThat(fellowshipOfTheRing)
.filteredOn("race", HOBBIT)
.containsOnly(sam, frodo, pippin, merry);
java8
assertThat(fellowshipOfTheRing)
.filteredOn(character -> character.getRace().equals(HOBBIT))
.containsOnly(sam, frodo, pippin, merry);
참고자료