Spring Boot/JUnit5

[JUnit5] JUnit 5: 확장 모델

수수한개발자 2022. 7. 22.
728x90

 

JUnit 4의 확장 모델은 @RunWith(Runner), TestRule, MethodRule 이 있는데

JUnit 5의 확장 모델은 단 하나, Extension 이다.

 

등록방법에는 3가지가 있다.

 

등록 방법

  • 선언적인 등록 @ExtendWith
  • 프로그래밍 등록 @RegisterExtension
  • 자동 등록 자바 ServiceLoader 이용

 

@ExtendWith

package me.jisu.javatest;

import jdk.jfr.Threshold;
import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
import org.junit.jupiter.api.extension.ExtensionContext;

import java.lang.reflect.Method;

public class FindSlowTestExtension implements BeforeTestExecutionCallback, AfterTestExecutionCallback {

    private static final long THRESHOLD = 1000L;

    @Override
    public void beforeTestExecution(ExtensionContext context) throws Exception {
        ExtensionContext.Store store = getStore(context);
        store.put("START_TIME", System.currentTimeMillis());
    }

    @Override
    public void afterTestExecution(ExtensionContext context) throws Exception {
        Method requiredTestMethod = context.getRequiredTestMethod();
        SlowTest annotation = requiredTestMethod.getAnnotation(SlowTest.class);
        String testMethodName = context.getRequiredTestMethod().getName();
        ExtensionContext.Store store = getStore(context);
        Long start_time = store.remove("START_TIME", long.class);
        long duration = System.currentTimeMillis() - start_time;
        if (duration > THRESHOLD && annotation == null) {
            System.out.printf("Please consider mark method [%s] with @SlowTest.\n", testMethodName);
        }
    }

    private ExtensionContext.Store getStore(ExtensionContext context) {
        String testClassName = context.getRequiredTestClass().getName();
        String testMethodName = context.getRequiredTestMethod().getName();
        ExtensionContext.Store store = context.getStore(ExtensionContext.Namespace.create(testClassName, testMethodName));
        return store;
    }
}

 

 위와 같이 BeforeTestExecutionCallback, AfterTestExecutionCallback를 상속받는 클래스를 만들어 줍니다.

그리고 만약에 실행시간이 1초가 넘는다면 @SlowTest를 써달라는 메세지를 메소드이름과 함께 출력해줍니다.

 

 

@ExtendWith(FindSlowTestExtension.class)
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class StudyTest {
    @Order(1)
    @Test
    @DisplayName("스터디 만들기 \uD83D\uDe31 slow")
    @Disabled
    void create_new_study_again() throws InterruptedException {
        Thread.sleep(1005L);
        System.out.println(this);
        System.out.println(value++);
        System.out.println("create1");
    }
}

 이렇게 클래스 위의 @ExtendWith 어노테이션으로 사용할 수 있습니다.

그리고 메소드에서 쓰레드를 줘서 1005L가 걸리게 합니다. 이때  FindSlowTestExtension 클래스에서 Method requiredTestMethod = context.getRequiredTestMethod();
SlowTest annotation = requiredTestMethod.getAnnotation(SlowTest.class); 와 annotation ==null 일때 조건을 줘서 

@SlowTest가 붙어있지 않을때만 메세지를 출력하게 해줍니다.

 

 

하지만 테스트를 하다보면 메소드마다 걸리는 시간 THRESHOLD를 다르게 주고 싶을때도 있습니다.

위의 방벙에서는 사용하지 못합니다.

그럴 때는 생성자를 통해 넣어 줄 수 있습니다.

 

@RegisterExtension

 

public class FindSlowTestExtension implements BeforeTestExecutionCallback, AfterTestExecutionCallback {

    private long THRESHOLD;

    public FindSlowTestExtension( long THRESHOLD) {
        this.THRESHOLD= THRESHOLD;
    }
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class StudyTest {

    int value = 1;

    @RegisterExtension
    static FindSlowTestExtension findSlowTestExtension =
            new FindSlowTestExtension(1000L);

이런식으로 사용할 수 있습니다.

 

728x90

'Spring Boot > JUnit5' 카테고리의 다른 글

[JUnit5] 마이그레이션  (0) 2022.07.22
[Junit5] junit-platform.properties  (0) 2022.07.22
[JUnit5] 테스트 순서  (0) 2022.07.22
[JUnit5] 테스트 인스턴스  (0) 2022.07.22
[JUint5] 테스트 반복하기  (0) 2022.07.22

댓글