본문 바로가기
Spring

Spring_5주차-(1)

by shulk 2023. 11. 28.

테스트

1. Before - After

* 각각의 기능 설명은 프린트 문에 적힌거다.

 

2. @DisplayName, @Nested , @TestMethodOrder

* @DisplayName은 테스트의 내용을 한눈에 알아볼 수 있게 네이밍 해줄 수 있다.

* 지금은 메소드 한개만 실행해서 잘 모르나 클래스 자체나 메소드 여러개 실행시 구별하기 쉽도록 하기 위해 

@DisplayName 사용한다.

 

* @Nested는 주제별로 테스트를 그룹지어서 파악하기 좋게 하려고 한다.(그냥 일반 클래스랑 같은듯)

* 테스트 메소드 수행 순서를 정할때는 @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 어노테이션 설정 해야한다.

* 설정하고 각 메소드에 @Order(값)  순서를 정한다. 

@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");
    }
}

 

3. @RepeatedTest , @ParameterizedTest

* @RepeatedTest를 사용하여 해당 테스트 메서드를 반복할 수 있고 name 속성을 사용하여 네이밍할 수 있다.

* totalRepetitions랑currentRepetition는 정해진 이름이고 value값 포매팅을 위한거다. (갭처 확인해보면 1/5,2/5...)

@RepeatedTest(value = 5, name = "반복 테스트 {currentRepetition} / {totalRepetitions}")
void repeatTest(RepetitionInfo info) {
    System.out.println("테스트 반복 : " + info.getCurrentRepetition() + " / " + info.getTotalRepetitions());
}

 

* @ParameterizedTest 사용하면 한개의 테스트 메소드에 매개변수값 여러번의 경우를 테스트 할 수 있다.

* @ValueSource를 이용해서 num에 넣을값들 설정한다.

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

 

4. Assertions

 

(1) Assertions.assertEquals(expected, actual)

먼저 각 테스트 메소드에서 calculator있는거보니 main에 있는 Calculator파일 클래스 이용하려한다. 

이때 @BeforeEach 이용해서 생성한다.

 

* assertEquals() 메서드는 첫 번째 파라미터에 예상값을 넣고 두 번째 파라미터에 테스트 결과값(실제값)을 넣어주고 맞나 틀리나 확인한다.

* assertNotEquals()는  assertEquals()의 반대

* 3번째 매개변수에 람다식으로 메시지를 넣어두면 테스트 실패 시 해당 메시지가 출력된다.. (new Supplier<String>())

 

(2) Assertions.assertTrue(boolean)

* assertTrue(), assertFalse() 메서드는 해당 파라미터 값이 true,false인지 확인한다.

(오른쪽 갭처는 main의 calculator클래스에 있는 메소드중 하나)

 

(3) Assertions.assertNotNull(actual)

* assertNotNull() 메서드는 해당 파라미터 값이 null이 아님을 확인하고 asserNull()은 반대로 null인지 확인

 

(4) Assertions.assertThrows(expectedType, executable)

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

 

 

(5) Given - When - Then

* 이거는 테스트 코드 스타일을 표현 하는 방식을 말하고

- 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("계산기 연산 실패 테스트 : 연산자가 잘못됐을 경우")
    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());
    }
}

 

 

5. Mockito

예를들어 어떤 서비스를 테스트 할때 그 서비스 수행에 필요한 레포지토리를 서비스 생성할때 생성자로 레포지토리를 전달 해줘야하는데 이부분은 Mockito의 가짜 객체를 이용한다.

* Mockito 라이브러리에서 제공 해주는 가짜 객체 생성  Mock Object를 이용하고, Mockito 는 따로 의존할 필요 없이 이미 사용 할 수 있게 스프링부트에서 가져오고 있다.

* 이렇게 @ExtendWith(MockitoExtension.class)  설정해준다.

* 이러고 이제 가짜 객체로 만들고자 하는 클래스 혹은 인터페이스 선언을 @Mock 달아준다.

 

* 테스트 메소드에서 가짜 객체 생성할때 main의 해당 로직 생성 순서와 똑같이 맞춰야한다. 안그러면 오류난다

(main캡처보면 @RequiredArgsConstructor 방식으로

productRepository  => productFolderRepository  => folderRepository 순서대로 전달하고 있으니 테스트쪽도 이 순서대로 해줘야한다)

main의 서비스 테스트
main의 서비스

'Spring' 카테고리의 다른 글

@QueryHint 와 @Transaction readOnly 차이 / 비공개  (0) 2024.04.08
Spring_5주차-(2)  (0) 2023.12.04
Spring_4주차-(2)  (0) 2023.11.14
Spring_4주차-(1)  (0) 2023.11.10
Spring_3주차-(1)  (0) 2023.11.07