AssertJ란?
JUnit으로 테스트 코드 작성시 JUnit에서 제공하는 Assertion 에는 가독성에 한계가 있다. 이를 해결하기 위해 AssertJ 라이브러리를 통해 좀 더 직관적인 테스트 코드를 작성할 수 있도록한다. 아래는 두 값이 같은지 확인하는 JUnit Assertion과 AssertJ를 활용했을 때의 비교이다.
assertEquals("test context", "a", "a"); // JUnit
assertThat("a").as("test context").isEqualTo("a"); // AssertJ
사용해보기
AssertJ를 활용한 코드는 대부분 아래와 같은 형식으로 작성할 수 있다.
assertThat(objectUnderTest).method1().method2().⋯
잘못된 사용 예시
- assertion 호출을 잊지마라. assertThat만으로는 어떤 assertion도 만들 수 없다. assertThat만 사용할 경우 절대 fail이 발생하지 않는다.
예시:
// DON'T DO THIS ! It does not assert anything and passes
assertThat(1 == 2);
// DO THIS: (fails as expected)
assertThat(1).isEqualTo(2);
- assertion 이후에 as()를 호출하지마라. assertion 이후의 as는 작동하지 않을 수 있다.
예시:
// DON'T DO THIS ! as/describedAs have no effect after the assertion
assertThat(actual).isEqualTo(expected).as("description");
assertThat(actual).isEqualTo(expected).describedAs("description");
// DO THIS: use as/describedAs before the assertion
assertThat(actual).as("description").isEqualTo(expected);
assertThat(actual).describedAs("description").isEqualTo(expected);
- assertion 이후에 FailMessage 및 overridingErrorMessage를 호출하지마라. 작동하지 않을 수 있다.
// DON'T DO THIS ! overridingErrorMessage/withFailMessage have no effect after the assertion
assertThat(actual).isEqualTo(expected).overridingErrorMessage("custom error message");
assertThat(actual).isEqualTo(expected).withFailMessage("custom error message");
// DO THIS: use overridingErrorMessage/withFailMessage before the assertion
assertThat(actual).overridingErrorMessage("custom error message").isEqualTo(expected);
assertThat(actual).withFailMessage("custom error message").isEqualTo(expected);
- comparator를 assertion 이전에 호출하라.
예시:
// DON'T DO THIS ! Comparator is not used
assertThat(actual).isEqualTo(expected).usingComparator(new CustomComparator());
// DO THIS:
assertThat(actual).usingComparator(new CustomComparator()).isEqualTo("a");
주요 메소드
isEqualTo
: 실제 값과 주어진 값이 같은지 확인한다.
public SELF isEqualTo(Object expected)
예시:
// assertions succeed
assertThat("abc").isEqualTo("abc");
assertThat(new HashMap<String, Integer>()).isEqualTo(new HashMap<String, Integer>());
// assertions fail
assertThat("abc").isEqualTo("123");
assertThat(new ArrayList<String>()).isEqualTo(1);
as
: 이후에 호출된 assertion의 설명을 설정한다.
public SELF as(String description, Object... args)
try {
// set an incorrect age to Mr Frodo which is really 33 years old.
frodo.setAge(50);
// specify a test description (call as() before the assertion !), it supports String format syntax.
assertThat(frodo.getAge()).as("check %s's age", frodo.getName()).isEqualTo(33);
} catch (AssertionError e) {
assertThat(e).hasMessage("[check Frodo's age]\n
expected: 33\n
but was : 50");
}
contains
: 실제 그룹에 주어진 값이 포함되어 있는지 확인한다.
public SELF contains(ELEMENT... values)
예시:
Iterable<String> abc = newArrayList("a", "b", "c");
// assertions will pass
assertThat(abc).contains("b", "a");
assertThat(abc).contains("b", "a", "b");
// assertion will fail
assertThat(abc).contains("d");
containsExactly
: 실제 그룹에 지정된 값이 포함되어 있는지 순서대로 확인한다.
public SELF containsExactly(ELEMENT ... values)
예시:
// an Iterable is used in the example but it would also work with an array
Iterable<Ring> elvesRings = newArrayList(vilya, nenya, narya);
// assertion will pass
assertThat(elvesRings).containsExactly(vilya, nenya, narya);
// assertion will fail as actual and expected order differ
assertThat(elvesRings).containsExactly(nenya, vilya, narya);
assertThatThrownBy
: 코드에서 예외가 발생하는지 확인한다.
public static AbstractThrowableAssert<?,? extends Throwable> assertThatThrownBy(ThrowableAssert.ThrowingCallable shouldRaiseThrowable, String description, Object... args)
예시:
import static org.assertj.core.api.Assertions.*;
assertThatThrownBy(() -> {
// 확인할 코드
}).isInstanceOf(IndexOutOfBoundsException.class) // IndexOutOfBoundsException이 발생한 경우
.hasMessageContaining("Index: 2, Size: 2"); // Exception 메시지가 "Index: 2, Size: 2"인 경우
assertThatExceptionOfType
:assertThatThrownBy
와 같은 목적이지만 가독성이 더 좋은 경우 이 메소드를 사용한다.
public static <T extends Throwable> ThrowableTypeAssert<T> assertThatExceptionOfType(Class<? extends T> exceptionType)
예시:
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
assertThatExceptionOfType(IndexOutOfBoundsException.class)
.isThrownBy(() -> {
// 확인할 코드
}).withMessageMatching("Index: \\d+, Size: \\d+");
자주 발생하는 Exception의 경우마다 별도의 메서드를 제공하고 있다.
- assertThatIllegalArgumentException()
- assertThatIllegalStateException()
- assertThatIOException()
- assertThatNullPointerException()
hasSize
: 실제 그룹의 값의 개수가 주어진 값과 같은지 확인한다.
public SELF hasSize(int expected)
예시:
// assertions will pass
assertThat(new String[] { "a", "b" }).hasSize(2);
assertThat(Arrays.asList(1, 2, 3)).hasSize(3);
// assertions will fail
assertThat(new ArrayList()).hasSize(1);
assertThat(new int[] { 1, 2, 3 }).hasSize(2);
댓글남기기