-
[Java] @BeforeAll과 static block의 차이백엔드/Java 2023. 3. 1. 09:00반응형
책에서 메모리 구조를 공부하다가 갑자기 테스트 어노테이션을 찾아보라는 말이 나왔다. @BeforeClass를 찾아보라고 했는데, JUnit4가 @BeforeClass이고, JUnit5는 @BeforeAll을 사용한다.
@BeforeAll
@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented @API(status = STABLE, since = "5.0") public @interface BeforeAll { }
- 어노테이션이나 메서드에 @BeforeEach를 붙일 수 있다.
- 런타임(프로그램 종료 전까지)동안 어노테이션이 남아있다.
- JavaDoc을 생성할 때, @BeforeEach도 같이 나온다.
문서에 나온 내용은 아래와 같다.
- 현재 테스트 클래스안에 있는 모든 테스트가 시작되기 전에 한 번만 실행한다.
- 무조건 반환 유형이 void이어야 하며, private를 사용하지 말아야하고, static 키워드를 사용해야 한다.
- 슈퍼클래스 - 서브클래스가 있으면 슈퍼 클래스의 @BeforeAll부터 실행된다.
- 인터페이스도 마찬가지로 인터페이스의 구현체보다 인터페이스에 있는 @BeforeAll부터 실행 된다.
- 한 테스트 클래스에 여러 개의 @BeforeAll이 있으면 랜덤으로 실행된다. (실행 순서가 보장되지 않으므로 최대 1개 만드는 것을 권장한다.)
@BeforeAll의 경우엔 테스트 클래스를 실행할 때, 딱 한 번만 실행되는 것이 static block과 비슷하다.
public A { static { ... } }
static block은 처음 객체가 만들어질 때 딱 한 번만 실행된다.
@BeforeAll과 static block은 무엇이 다를까?
@BeforeAll과 static block의 공통점은 테스트 메서드가 전부 실행되기 전, 객체가 처음 생성될 때 딱 한 번만 호출된다는 것이다.
하지만 가장 큰 차이점은 static block의 경우엔 JVM에 의해 호출이 되면 즉시 실행하게 되고, @BeforeAll은 JUnit에 의해 호출이 되기 때문에 테스트 메서드가 실행되기 전에 실행한다는 점이다. 거기다가 만약 static block에서 에러가 발생하게 된다면 JUnit의 이점을 포기하는 것과 마찬가지이다. 이 부분은 당장 @BeforeAll 대신 static block을 사용해보면 알 수 있다.
나는 객체를 생성할 때 이상한 값을 주입하면, IllegalArgumentException을 던지도록 했다. static block안에서 객체에 이상한 값을 주입해 생성하게 되면 IllegalArgumentException, ExceptionInInitializerError, NoClassDefFoundError로 여러가지 에러가 터지게 된다.
에러 로그를 살펴보는게 아니라면 위 사진과 같이 테스트 메서드가 문제라는 착각이 생길 수도 있다.
@BeforeAll을 사용하여 확인해보면 IllegalArgumentException이 나오게 되고, 왼쪽엔 initializationError가 나오게 된다. 그래서 에러 로그를 직접 살피지 않아도 바로 어디가 문제인지 파악할 수 있게 된다.
그리고 테스트 클래스가 슈퍼 클래스(A), 서브 클래스(B)가 있을 때, A 클래스에 @BeforeAll은 서브 클래스로 상속이 되지만, static block은 상속이 되지 않는다는점. 마지막으로 Mockito와 같은 프레임워크를 사용한다면 @BeforeAll은 함께 사용할 수 있지만, static block은 해당 프레임워크의 도움을 받지 못하게 된다.
결론 @BeforeEach, @BeforeAll을 쓰자
반응형'백엔드 > Java' 카테고리의 다른 글
[Concurrency] Software Transactional Memory (Beautiful concurrency) (0) 2024.04.29 [Java, Concurrency] Compare and Swap 알고리즘 (CAS) (0) 2024.04.14 [Java] Enum 내부 코드 확인하기 (0) 2023.02.22 [Java] 표준 어노테이션 (0) 2023.02.21 [Java] var는 사용해도 되는 것일까? (0) 2023.02.13