1. AssertJ란?
AssertJ란 asssertion(직역 : 주장)을 제공하는 자바 라이브러리로 에러 메세지와 테스트 코드의 가독성을 높여주는 라이브러리이다.
junit5에서 제공하는 Assertions의 assert는 인자 순서 (expected, actual)의 순서가 헷갈릴 수 있는데 Assertions보다 가독성이 좋아진다.
assertEquals(expected, actual);
assertThat(actual).isEqualTo(expected);
- 메소드 체이닝을 지원하기 때문에 좀 더 깔끔하고 읽기 쉬운 테스트 코드를 작성할 수 있다.
- 개발자가 테스트를 하면서 필요한 거의 모든 메소드를 제공한다.
2. 의존성 추가
//maven
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.21.0</version>
<scope>test</scope>
</dependency>
//gradle
testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.21.0'
3. 메소드 임폴트
import static org.assertj.core.api.Assertions.*;
4. 테스트 대상 지정
assertThat(테스트 타켓).메소드1().메소드2().메소드3();
5. 문자열 테스트 예시
@Test
@DisplayName("테스트 코드 작성")
public void numTest() {
assertThat("Hello, world! Nice to meet you.") // 주어진 "Hello, world! Nice to meet you."라는 문자열은
.isNotEmpty() // 비어있지 않고
.contains("Nice") // "Nice"를 포함하고
.contains("world") // "world"도 포함하고
.doesNotContain("ZZZ") // "ZZZ"는 포함하지 않으며
.startsWith("Hell") // "Hell"로 시작하고
.endsWith("u.") // "u."로 끝나며
.isEqualTo("Hello, world! Nice to meet you."); // "Hello, world! Nice to meet you."과 일치합니다.
}
6. 숫자 테스트 예시
@Test
@DisplayName("숫자 테스트")
public void test() {
assertThat(3.14d) // 주어진 3.14라는 숫자는
.isPositive() // 양수이고
.isGreaterThan(3) // 3보다 크며
.isLessThan(4) // 4보다 작습니다
.isEqualTo(3, offset(1d)) // 오프셋 1 기준으로 3과 같고
.isEqualTo(3.1, offset(0.1d)) // 오프셋 0.1 기준으로 3.1과 같으며
.isEqualTo(3.14); // 오프셋 없이는 3.14와 같습니다
}
7. description (에러 메세지)
- 에러 메세지의 경우 as라는 메서드로 지정할 수 있다.
- 단, as 메서드는 assertions이 수행되기전에 사용해야한다.
package assertj;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import static org.assertj.core.api.Assertions.*;
public class FailMessageTest {
class Member {
private String name;
private int age;
public Member(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
@Test
@DisplayName("에러 메세지 출력")
public void test() {
Member frodo = new Member("Frodo", 33);
frodo.getAge();
// failing assertion, remember to call as() before the assertion, not after !
assertThat(frodo.getAge())
.as("check %s's age", frodo.getName()) // as를 assertion 이전에 넣는다.
.isEqualTo(100);
}
}
메세지 결과
[check Frodo's age] expected:<100> but was:<33>
8. filtering assertions - iterables or array에 적용
@Test
@DisplayName("람다식을 이용한 필터링")
public void filterTest() {
//given
List<Member> list = new ArrayList<>();
Member kim = new Member("Kim", 22);
Member park = new Member("Park", 25);
Member lee = new Member("Lee", 22);
Member amy = new Member("Amy", 25);
Member jack = new Member("Jack", 22);
list.add(kim); list.add(park);
list.add(lee); list.add(amy);
list.add(jack);
// when && then
assertThat(list).filteredOn(human -> human.getName().contains("a"))
.containsOnly(park, jack);
}
9. extracting
- 리스트에서 특정 필드만 뽑아서 테스트 가능
@Test
@DisplayName("특정 속성 추출 테스트")
public void extractTest() {
//given
List<Member> list = new ArrayList<>();
Member kim = new Member("Kim", 22);
Member park = new Member("Park", 25);
Member lee = new Member("Lee", 22);
Member amy = new Member("Amy", 25);
Member jack = new Member("Jack", 22);
list.add(kim);
list.add(park);
list.add(lee);
list.add(amy);
list.add(jack);
// then
assertThat(list).extracting("name")
.contains("Kim", "Park", "Lee", "Amy", "Jack");
}
- 여러 필드를 검사하고 싶을 경우 tuple 사용
@Test
@DisplayName("특정 속성 추출 테스트2")
public void extractTest2() {
//given
List<Member> list = new ArrayList<>();
Member kim = new Member("Kim", 22);
Member park = new Member("Park", 25);
Member lee = new Member("Lee", 22);
Member amy = new Member("Amy", 25);
Member jack = new Member("Jack", 22);
list.add(kim);
list.add(park);
list.add(lee);
list.add(amy);
list.add(jack);
// then
assertThat(list).extracting("name", "age")
.contains(tuple("Kim", 22),
tuple("Park", 25),
tuple("Lee", 22),
tuple("Amy", 25),
tuple("Jack",22));
}
10. Soft assertions
- Soft assertions를 사용하면 모든 assertions을 실행한 후 실패 내역만 확인 가능
@Test
@DisplayName("soft assertions로 한번에 검증")
public void softAssertionsTest() {
int num1 = 3;
int num2 = 5;
String str = "hello";
SoftAssertions softly = new SoftAssertions();
softly.assertThat(num1).as("num1 is %d", num1).isEqualTo(5);
softly.assertThat(num2).as("num2 is %d", num2).isEqualTo(6);
softly.assertThat(str).as("str is %s", str).isEqualTo("hi");
softly.assertAll();
}
11. Exception 처리 테스트
- assertThatThrownBy() 메서드를 통해서 예외 처리를 할 수 있다.
@Test
public void exceptionAssertionTest1() {
// WHEN
Throwable thrown = catchThrowable(() -> { throw new Exception("boom!"); });
// THEN
assertThat(thrown).isInstanceOf(Exception.class)
.hasMessageContaining("boom");
}
@Test
public void exceptionAssertionTest2() {
assertThatThrownBy(() -> { throw new Exception("boom!"); })
.isInstanceOf(Exception.class)
.hasMessageContaining("boom");
}
12. 자주 쓰이는 예외 처리 systax
- assertThatNullPointerException
- assertThatIllegalArgumentException
- assertThatIllegalStateException
- assertThatIOException
@Test
public void exceptionAssertionTest3() {
assertThatIOException().isThrownBy(() -> { throw new IOException("boom!"); })
.withMessage("%s!", "boom")
.withMessageContaining("boom")
.withNoCause();
}
REFERENCE
https://pjh3749.tistory.com/241
https://steady-coding.tistory.com/351
'Test' 카테고리의 다른 글
Mockito && 스프링부트 테스트 관련 어노테이션 정리 (0) | 2021.11.17 |
---|---|
무엇을 어떻게 테스트할 것인가 (feat : 권용근님) (0) | 2021.11.17 |
단위 테스트(Unit Test) (0) | 2021.11.17 |
테스트 종류 (0) | 2021.11.17 |
Junit5 기본 사용법 정리 (0) | 2021.11.15 |