ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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을 쓰자

    반응형

    댓글

Designed by Tistory.