아래 사이트에 게시된 글을 정리/번역해 작성한 글입니다. 작성 중에 생략된 내용이 있을 수 있습니다.
https://www.baeldung.com/assertj-exception-assertion
AssertJ의 excption 전용 assertion을 살펴보자.
try {
// ...
} catch (Exception e) {
// assertions
}
AssertJ를 사용하지 않는다면 위처럼 테스트코드를 작성할 수 있다. 하지만 만약 예외가 발생하지 않은 경우, 테스트가 의도와 다르게 성공으로 표시된다.
Java 8을 사용하면 AssertJ와 람다 표현식을 이용해 예외에 대한 어설션을 쉽게 수행할 수 있다.
assertThatThrownBy()IndexOutOfBoundsException 예외를 발생하는 예시를 살펴보자. assertThatThrownBy() 메서드에 람다 표현식으로 예외를 던질 수 있는 메서드를 넘겨주고 있다.
assertThatThrownBy(() -> {
List<String> list = Arrays.asList("String one", "String two");
list.get(2);
}).isInstanceOf(IndexOutOfBoundsException.class)
.hasMessageContaining("Index: 2, Size: 2");
다양한 표준 AssetJ 어설션을 연결해서 사용할 수 있다.
.hasMessage("Index: %s, Size: %s", 2, 2)
.hasMessageStartingWith("Index: 2")
.hasMessageContaining("2")
.hasMessageEndingWith("Size: 2")
.hasMessageMatching("Index: \\d+, Size: \\d+")
.hasCauseInstanceOf(IOException.class)
.hasStackTraceContaining("java.io.IOException");
assetThatExceptionOfType()기본 아이디어는 위와 비슷하지만 제일 먼저 exception type을 명시한다.
assertThatExceptionOfType(IndexOutOfBoundsException.class)
.isThrownBy(() -> {
// ...
}).hasMessageMatching("Index: \\d+, Size: \\d+");
assertThatIOExcption() and Other Common TypesAssetJ는 기본 예외 타입에 대한 wrapper를 제공한다.
assertThatIOException().isThrownBy(() -> {
// ...
});
assertThatIllegalArgumentException()assertThatIllegalStateException()assertThatIOException()assertThatNullPointerException()when과 then을 구분하기 위해 catchThrowable()을 이용해 다음과 같이 작성할 수 있다.
// when
Throwable thrown = catchThrowable(() -> {
// ...
});
// then
assertThat(thrown)
.isInstanceOf(ArithmeticException.class)
.hasMessageContaining("/ by zero");
AssertJ는 catchThrowableOfType() 메서드와 같이 custom exception의 필드를 검사할 수 있는 몇가지 편리한 방법을 제공한다.
다음과 같이 CityNotFoundException이라는 이름의 커스텀 예외를 예시로 들어보자.
public class CityNotFoundException extends RuntimeException {
private String city;
private String message;
CityNotFoundException(String city, String message) {
this.city = city;
this.message = message;
}
// Getters
}
다음은 CityNotFoundException을 발생시키는 예시 메서드이다. 해당 예외는 city와 message 필드를 가지고 있다.
public final class CityUtils {
private static final List<String> CITIES = Arrays.asList("Tamassint", "London", "Madrid", "New york");
public static String search(String searchedCity) {
return CITIES.stream()
.filter(searchedCity::equals)
.findFirst()
.orElseThrow(() -> new CityNotFoundException(searchedCity, "The specified city is not found"));
}
}
커스텀 예외의 필드를 검사할 수 있는 테스트 케이스는 다음과 같이 작성할 수 있다. catchThrowableOfType()을 통해 커스텀 예외를 캐치하고 assertThat() 으로 예외의 필드 값을 체크한다.
@Test
public void whenUsingCatchThrowableOfType_thenAssertField() {
String givenCity = "Paris";
CityNotFoundException exception = catchThrowableOfType(() -> CityUtils.search(givenCity), CityNotFoundException.class);
assertThat(exception.getCity()).isEqualTo(givenCity);
assertThat(exception.getMessage()).isEqualTo("The specified city is not found");
}
assertThatThrownBy()를 이용해서 동일한 테스트를 할 수 있다.
@Test
public void whenUsingAssertThatThrownBy_thenAssertField() {
String givenCity = "Geneva";
assertThatThrownBy(() -> CityUtils.search(givenCity)).isInstanceOf(CityNotFoundException.class)
.extracting("city")
.isEqualTo(givenCity);
}