[초록스터디] JUnit5 테스트 코드 작성법 공부

2024. 5. 10. 23:58·study

JUnit이란?

자바 언어를 사용하는 테스트 프레임워크중 하나로, 주로 단위 테스트를 작성하고 실행하는 데에 사용된다. 

 

 

 

@Test

해당 메서드가 테스트 메서드임을 나타낸다.  

return 타입이 void가 아니라면, 해당 메서드는 테스트 메서드가 아니다.

 

 

@DisplayName

해당 테스트의 이름을 나타낸다. 테스트의 이름을 한글로 작성하고 싶다면 @DisplayName 애노테이션을 사용하는 것이 좋다.

 

 

@Nested

해당 클래스가 중첩 클래스임을 나타낸다.

중첩 클래스- 클래스 내부에 선언된 클래스를 의미한다. 클래스의 의미를 명확하게 하기 위해서 중첩으로 표현한다.

@Nested 애노테이션을 사용하면 해당 메서드는 중첩 클래스 내부에 있는 것으로 판단한다.

 

 

 

@Disabled

해당 테스트를 비활성화한다. @Disabled 애노테이션은 @Test 애노테이션과 함께 사용된다.

클래스에도 적용 가능하며 이 경우 해당 클래스의 모든 테스트가 비활성화 된다. 

 

 

 

assertEquals

두 값이 같은지 비교한다. 두 값이 같다면 테스트는 성공하며, 두 값이 다르다면 테스트는 실패한다.

'org.junit.jupital.api.Assertions' 클래스에 정의되어 있다. ('static'으로 임포트하여 사용)

'assertEquals' 메서드는 'assertEquals(expected,  actual)' 형태로 오버로딩 되어있다.

 

 

객체 또한 equals를 호출하기 때문에 아래 테스트 코드는 성공하지 못한다.

void assertEquals_메서드로_두_객체가_같은지_비교한다() {
            class LocalObject {
                private final int value;

                public LocalObject(int value) {
                    this.value = value;
                }
            }

            final var a = new LocalObject(1);
            final var b = new LocalObject(1);

            // TODO: LocalObject 클래스의 equals를 재정의하여 아래 코드가 테스트를 성공시키도록 해주세요.
            assertEquals(a, b);
        }

 

 

 

LocalObject 클래스에 equals 메서드를 정의하여 해결한다.

 void assertEquals_메서드로_두_객체가_같은지_비교한다() {
            class LocalObject {
                private final int value;

                public LocalObject(int value) {
                    this.value = value;
                }

                public boolean equals(Object o){
                    if (o instanceof LocalObject){
                        return this.value==(((LocalObject) o).value);
                    }
                    return false;
                }
            }

            final var a = new LocalObject(2);
            final var b = new LocalObject(2);

            // TODO: LocalObject 클래스의 equals를 재정의하여 아래 코드가 테스트를 성공시키도록 해주세요.
            assertEquals(a, b);
        }

테스트 성공

 

 

assertEquals(expected, actual, message)는 테스트가 실패했을 때 출력되는 메시지를 지정할 수 있다.

'message' 는 테스트가 실패했을 때 출력되는 메시지이다.

 

 

 

 

assertNotEquals

두 값이 다르다면 테스트를 성공시킨다.

 

 

 

 

assertThrows

특정 예외가 발생하는지 비교한다. 특정 예외가 발생한다면 테스트는 성공하며, 특정 예외가 발생하지 않

assertThrows(expectedType, executable) 형태로 오버로딩 되어있다.

@Test
        @DisplayName("assertThrows 메서드로 특정 예외가 발생하는지 비교한다")
        void assertThrows_메서드로_특정_예외가_발생하는지_비교한다() {
            // TODO: try-catch문을 사용하지 않고 assertThrows 메서드를 사용하여 테스트가 성공하도록 해주세요.
            try {
                causeException();
            } catch (Exception e) {
                return;
            }

            throw new RuntimeException("예외가 발생하지 않았습니다.");
        }

 

 

위 코드를 assertThrows 메서드가 들어간 코드로 바꾸어보기

 

 

@Test
        @DisplayName("assertThrows 메서드로 특정 예외가 발생하는지 비교한다")
        void assertThrows_메서드로_특정_예외가_발생하는지_비교한다() {
            // TODO: try-catch문을 사용하지 않고 assertThrows 메서드를 사용하여 테스트가 성공하도록 해주세요.
            /*try {
                causeException();
            } catch (Exception e) {
                return;
            }
             */
            assertThrows(Exception.class, ()-> causeException());


        }

 

 

 

assertDoesNotThrow

특정 예외가 발생하지 않는다면 테스트를 성공시킨다. 메서드를 사용하지 않아도 테스트는 성공하지만, 테스트의 의도를 명확하게 표현할 수 없다.

 

 

 

assertAll

여러 검증 코드를 한 번에 실행한다.  'assertAll(executables)' 형태로 오버로딩 되어있다.

'assertAll'을 사용하는 이유는 여러 검증 코드가 존재할 때 문제가 발생한다면 어떤 검증 코드에서 문제가 발생했는지 알기 어렵기 때문이다.

 

assertAll(
                ()->assertEquals(3, 1 + 2),
                ()-> assertEquals(5, 3 + 2),
                ()->assertEquals(21, 7 * 3),
                ()->assertEquals(32, 3 * 7 ^ 5),
                ()->assertEquals(4, 7 * 3 / 5 + 33 / 21),
                ()->assertEquals(22, 33 * 3 / 5 + 7 / 2),
                ()->assertEquals(22, 33 * 3 / 5 + 7 / 2 + 1)

            );

 

실행 결과

assertAll을 사용해 모든 테스트의 결과를 한 번에 볼 수 있다.

 

 

 

 

 

@ParameterizedTest

테스트에 필요한 파라미터를 제공하는 테스트이다.보통 테스트에 따라 @ValueSource와 @MethodSource 같은 애노테이션 중 적합한 애노테이션을 선택하여 테스트를 진행할 수 있다.ParameterizedTest를 사용하면 하나의 테스트 로직 내에서 여러 변수를 선언하지 않고, 주입받은 값을 활용하여 유연하고 단편화된 테스트 코드를 작성 할 수 있다.

@ParameterizedTest
        @ValueSource(ints={1,2,3,4})
        @DisplayName("ValueSource 애노테이션을 붙여 정수 매개변수를 여러 번 입력받는다")
        void ValueSource_애노테이션을_붙여_정수_매개변수를_여러_번_입력받는다(int value) {
            // TODO: `@ValueSource`를 사용하지 않고 여러 정수의 범위를 테스트하는 것과, `@ValueSource`를 사용해서 테스트하는 것의 차이를 비교해보세요.
            assertTrue(value>0 && value< 10);
        }

 

 

@MethodSource

메서드 이름을 인자로 받아들이며, 인자에서 호출된 메서드는 테스트 메서드에 전달될 인자를 반환한다.

@속성으로 사용된 해당 메서드는 'Arguments('ParameterizedTest' 에서 사용되는 값의 하나를 가리킨다)'  를 'Stream'에 담아 return 하여 각각의 Arguments가 테스트에 하나씩 전달 되도록 구현된 형태이다.

 

 @ParameterizedTest
        @MethodSource("methodSourcesTestArguments")
        @DisplayName("MethodSource 애노테이션을 붙여 Object 매개변수를 여러 번 입력받는다")
        void MethodSource_애노테이션을_붙여_Object_매개변수를_여러_번_입력받는다(Object object) { assertInstanceOf(Object.class, object);}
            // TODO: `MethodSource`를 사용하지 않고 Object 객체들을 직접 선언하여 테스트하는 방식과, `MethodSource`를 사용하여 Object를 입력받아 테스트하는 방식의 차이를 비교해보세요.
            /*Object object1 = new Object();
            Object object2 = new Object();
            Object object3 = new Object();
            Object object4 = new Object();

            assertInstanceOf(Object.class, object1);
            assertInstanceOf(Object.class, object2);
            assertInstanceOf(Object.class, object3);
            assertInstanceOf(Object.class, object4);
             */

        /**
         * `Arguments`를 `Stream` 내부에 여러 개 선언해줌으로서, 각 `Arguments`마다 각각의 테스트를 수행하도록 구현할 수 있습니다.
         */
        private static Stream<Arguments> methodSourcesTestArguments() {
            return Stream.of(
                    Arguments.arguments(new Object()),
                    Arguments.arguments(new Object()),
                    Arguments.arguments(new Object()),
                    Arguments.arguments(new Object())
            );
            
        }

 

 

'study' 카테고리의 다른 글

[초록스터디] 자바 컬렉션 API, Optional  (1) 2024.07.08
'study' 카테고리의 다른 글
  • [초록스터디] 자바 컬렉션 API, Optional
zioni
zioni
  • zioni
    jiwon's dev.log
    zioni
  • 전체
    오늘
    어제
    • 분류 전체보기 (76)
      • spring & java (13)
      • Algorithm (14)
      • PS (37)
      • project (3)
      • experience (1)
      • etc (6)
      • study (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    백준
    자바
    java
    백준2525
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
zioni
[초록스터디] JUnit5 테스트 코드 작성법 공부
상단으로

티스토리툴바