[SPRING] 단위테스트_JUnit5

라미·2024년 3월 4일

spring

목록 보기
16/17
post-thumbnail

JUnit 5

JUnit 5 User Guide : JUnit 5 공식 user 가이드


🐥 @BeforeEach

@BeforeEach: 각각의 테스트 코드가 실행되기 전에 수행되는 메서드

@BeforeEach
void setUp() {
    System.out.println("각각의 테스트 코드가 실행되기 전에 수행");
}

🐥@AfterEach

@AfterEach: 각각의 테스트 코드가 실행된 후에 수행되는 메서드

void tearDown() {
    System.out.println("각각의 테스트 코드가 실행된 후해 수행되는 메서드이다\n");
}

🐥 @BeforeAll

@BeforeAll: 모든 테스트 코드가 실행되기 전에 최초로 수행

@BeforeAll
static void beforeAll() {
    System.out.println("모든 테스트 코드가 실행되기 전에 최초로 수행\n");
}

🐥 @AfterAll

@afterAll: 모슨 테스트 코드가 실행 된 후 마지막으로 실행

@afterAll
static void afterAll() {
        System.out.println("모든 테스트 코드가 수행된 후 마지막으로 수행");
    }

📝 테스트

@BeforeEach // 각각의 테스트 코드가 실행되기 전에 수행되는 메서드
void setUp() {
    System.out.println("각각의 테스트 코드가 실행되기 전에 수행 되는 메서드이다 @BeforeEach");

}

@AfterEach
void tearDown() {
    System.out.println("각각의 테스트 코드가 실행된 후해 수행되는 메서드이다 @AfterEach\n");
}

@BeforeAll
static void beforeAll() {
    System.out.println("모든 테스트 코드가 실행되기 전에 최초로 수행 @BeforeAll\n");
}

@AfterAll
static void afterAll() {
    System.out.println("모든 테스트 코드가 수행된 후 마지막으로 수행 @AfterAll");
}


@Test
void test1(){
    System.out.println("테스트 코드 작성1");
}

@Test
void test2(){
    System.out.println("테스트 코드 작성2");
}

📝 실행결과

모든 테스트 코드가 실행되기 전에 최초로 수행 @BeforeAll

각각의 테스트 코드가 실행되기 전에 수행 되는 메서드이다 @BeforeEach
테스트 코드 작성1
각각의 테스트 코드가 실행된 후해 수행되는 메서드이다 @AfterEach

각각의 테스트 코드가 실행되기 전에 수행 되는 메서드이다 @BeforeEach
테스트 코드 작성2
각각의 테스트 코드가 실행된 후해 수행되는 메서드이다 @AfterEach

모든 테스트 코드가 수행된 후 마지막으로 수행 @AfterAll

🐥 @DisplayName

@DisplayName : 테스트의 내용을 하눈에 알아볼 수 있게 네이밍 해준다

@Test
@DisplayName("테스트의 내용을 한눈에 알아볼 수 있게 네이밍")
void test1(){
    System.out.println("테스트 내용 빠르게 파악할 수 있게 도와주는  @DisplayName");
}

🐥 @Nested

@Nested : 주제 별로 테스트를 그룹지어서 파악하기 좋다 (class-method)

@Nested
@DisplayName("주제 별로 테스트를 그룹지어서 파악하기 좋습니다. @Nested")
class Test1 { // 클래스
    @Test
    @DisplayName("Test1 - test1()")
    void test1() { // 메서드
        System.out.println("Test1.test1");
    }

    @Test
    @DisplayName("Test1 - test2()")
    void test2() {
        System.out.println("Test1.test2");
    }
}

@Nested
@DisplayName("Test2 다른 주제")
class Test2 {
    @Test
    @DisplayName("Test2 - test1()")
    void test1() {
        System.out.println("Test2.test1");
    }

    @Test
    @DisplayName("Test2 - test2()")
    void test2() {
        System.out.println("Test2.test2");
    }
}

🐥 @Order

@Order : 테스트의 순서를 정해준다, 메서드에 붙이고 () 안에 순서를 정해준다
@TestMethodOrder(MethodOrderer.OrderAnnotation.class) : 클래스에 에너테이션 설정

@Nested
@DisplayName("주제 별로 테스트를 그룹지어서 파악하기 좋습니다.")
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class Test1 {
    @Order(1)
    @Test
    @DisplayName("Test1 클래스")
    void test() {
        System.out.println("\nTest1 클래스");
    }

    @Order(3)
    @Test
    @DisplayName("Test1 - test1()")
    void test1() {
        System.out.println("Test1.test1");
    }

    @Order(2)
    @Test
    @DisplayName("Test1 - test2()")
    void test2() {
        System.out.println("Test1.test2");
    }
}

🐥 @RepeatedTest(value = 5)

@RepeatedTest(value = 5, name = "반복 테스트 {currentRepetition} / {totalRepetitions}")
: 테스트 메서드를 반복하여 테스트 할 수 있다.
value = 5 : 반복 횟수를 지정
name = "반복 테스트 {currentRepetition} / {totalRepetitions} : displayname과 같이 사용 할 수 있다. currentRepetition / totalRepetitions 현재반복횟수와, 총반복 횟수를 나타내준다

@RepeatedTest(value = 5, name = "반복 테스트 {currentRepetition} / {totalRepetitions}")
void repeatTest(RepetitionInfo info) { // RepetitionInfo : 반복 값을 파라미터로 받을 수 있다
    //getCurrentRepetition() : 현재 반복 값 / getTotalRepetitions() : 총 반복 값
    System.out.println("테스트 반복 : " + info.getCurrentRepetition() + " / " + info.getTotalRepetitions());
}

🐥 @ParameterizedTest

@ParameterizedTest : 파라미터를 받아 테스트를 할 수 있다.
@ValueSource 파라미터 값을 전달 할 수 있다.

@DisplayName("파라미터 값 활용하여 테스트 하기")
@ParameterizedTest
@ValueSource(ints = {1, 2, 3, 4, 5, 6, 7, 8, 9})
void parameterTest(int num) {
    System.out.println("5 * num = " + 5 * num);
}

📝 실행결과


🐥 @Assertions

assertEquals(a,b) : a → 예상 값, b → 결과 값

@Test
@DisplayName("assertEquals")
void test1() {
    Double result = calculator.operate(5, "/", 2);
    assertEquals(2.5, result);
}

@Test
@Disabled
@DisplayName("assertEquals - Supplier")
void test1_1() {
    Double result = calculator.operate(5, "/", 0);
    // 테스트 실패 시 메시지 출력 (new Supplier<String>())
    assertEquals(2.5, result, () -> "연산자 혹은 분모가 0이 아닌지 확인해보세요!");
    // 람다식으로 테스트 실패시 메시지 출력
}

@Test
@DisplayName("assertNotEquals")
void test1_2() {
    Double result = calculator.operate(5, "/", 0);
    assertNotEquals(2.5, result); // 결과가 다름을 예상한다
}

예상결과와 실행결과가 다르면 아래와 같이 알려준다!


Assertions.assertTrue(boolean)

예상하는 값의 true,false 를 체크한다

@Test
@DisplayName("assertTrue 와 assertFalse")
void test2() {
    // boolean 값을 예측하는 메서드
    assertTrue(calculator.validateNum(9)); // true임을 예측
    assertFalse(calculator.validateNum(0)); // false 임을 예측
}

Assertions.assertNotNull(actual)

@Test
@DisplayName("assertNotNull 과 assertNull")
void test3() {
    Double result1 = calculator.operate(5, "/", 2);
    assertNotNull(result1); // null 이 아님을 예측
    Double result2 = calculator.operate(5, "/", 0);
    assertNull(result2); // mull 임을 예측
}

Assertions.assertThrows(expectedType, executable)
번째 파라미터에 예상하는 Exception 클래스 타입을 넣고 두 번째 파라미터에 실행 코드를 넣는다.
실행 코드의 결과가 예상한 해당 클래스 타입이라면 테스트에 성공한다.
'

@Test
@DisplayName("assertThrows")
void test4() {
    // 어떤 exception이 터질지 예측한다 assertThrows() -> 첫번째 파라미터, 예측하는 exception, 두번째 파라미터 -> 실행코드
    IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
            () -> calculator.operate(5, "?", 2));
    assertEquals("잘못된 연산자입니다.", exception.getMessage()); // exception 메세지 예측
}

Given - When - Then

Given-When-Then 패턴은 Test Code 스타일을 표현하는 방식

Given : 테스트를 실행하기 전에 테스트에 필요한 값(상태)를 미리 선언한다
When : 테스트를 실제로 실행 시킨다.
Then : 테스트 결과에 대해 예측하고 확인한다

class CalculatorTest {

    Calculator calculator;

    @BeforeEach
    void setUp() {
        calculator = new Calculator();
    }

    @Test
    @DisplayName("계산기 연산 성공 테스트")
    void test1() {
        // given : 테스트에 필요한 데이터를 준다
        int num1 = 5;
        String op = "/";
        int num2 = 2;

        // when : 실제로 실행을 시킨다
        Double result = calculator.operate(num1, op, num2);

        // then : 결과를 체크한다
        assertNotNull(result);
        assertEquals(2.5, result);
    }

    @Test
    @DisplayName("계산기 연산 실패 테스트 : 분모가 0일 경우")
    void test1_1() {
        // given
        int num1 = 5;
        String op = "/";
        int num2 = 0;

        // when
        Double result = calculator.operate(num1, op, num2);

        // then : 제대로 실패를 반환하는 지 체크한다
        assertNull(result);
    }

    @Test
    @DisplayName("계산기 연산 실패 테스트 : 연산자가 잘못됐을 경우")
    void test1_2() {
        // given
        int num1 = 5;
        String op = "?";
        int num2 = 2;

        // when - then : 실행, 예측을 한번에 한다
        IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> calculator.operate(5, "?", 2));
        assertEquals("잘못된 연산자입니다.", exception.getMessage());
    }
}

0개의 댓글