ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java] JUnit
    우아한 테크코스/테크코스 2020. 2. 5. 21:51
    반응형

    유닛 테스트

    컴퓨터 프로그래밍에서 소스 코드의 특정 모듈이 의도된 대로 정확히 작동하는지 검증하는 절차

    모든 함수와 메서드에 대한 테스트 케이스(Test case)를 작성하는 절차

    언제라도 코드 변경으로 인해 문제가 발생할 경우, 단시간 내에 이를 파악하고 바로잡을 수 있게 해줌

    이상적으론, 각 테스트 케이스는 서로 분리되어야 함

    가짜 객체(Mock Object)를 생성하는 것도 좋은 방법

    장점1. 문제점 발견

    유닛 테스트의 목적은 프로그램의 각 부분을 고립시켜 각각의 부분이 정확하게 동작하는지를 확인

    프로그램을 작은 단위로 쪼개서 각 단위가 정확하게 동작하는지 검사하고 이를 통해 문제 발생시 정확히 어느 부분이 잘못되었는지를 재빨리 확인할 수 있게 해줌 > 프로그램의 안정성이 높아짐

    개발 시간을 증가시키는 것처럼 보일 수 있지만, 개발 기간 중 대부분을 차지하는 디버깅 시간을 단축시킴으로 여유로운 프로그래밍을 가능하게 함

    장점2. 변경이 쉬움

    언제라도 유닛테스트를 믿고 리팩토링을 할 수 있음

    리팩토링 후에도 해당 모듈이 의도대로 작동할 수 있음을 유닛 테스트를 통해 확신할 수 있음(=회귀 테스트 Regression testing)

    어떻게 코드를 고치더라도 문제점을 금방 파악할 수 있고 수정된 코드가 정확히 동작하는지 쉽게 알 수 있게 되므로 코드를 변경하기 용이해짐

    좋은 유닛 테스트 디자인은 그 유닛이 사용되는 모든 경로를 커버할 수 있는 테스트 케이스를 만듦

    지속적인 유닛 테스트 환경 구축시 어떤 변화가 있떠라도 코드와 그 실행이 의도대로인지를 확인하고 검증할 수 있게 됨

    확립된 개발 방법과 유닛 테스트의 범위에 따라 프로그램의 정확성 좌우

    장점3. 통합이 간단

    유닛 자체의 불확실성을 제거해주므로 상향식(bottom-up) 테스트 방식에서 유용

    프로그램의 각 부분을 검증 후 그 부분을 합쳐서 다시 검증하는 통합 테스트에서 더 유용

    JUnit 5

    JUnit

    자바 프로그래밍 언어용 유닛 테스트 프레임워크

    컴파일 타입에 JAR로서 링크됨, 프레임워크는 org.junit 패키지 밑에 상주

    Junit 개요

    여러가지 스타일의 테스트가 가능

    Java 8 이상의 새로운 기능을 지원하기 위한 여러가지 혁신적인 기능 포함

    작동하려면 Java 8이 필요

    IntelliJ는 기본적으로 JUnit 5를 지원

    Maven 의존성(JUnit 5.x.0)

    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.x.0</version>
        <scope>test</scope>
    </dependency>

    구조 (1/3) - JUnit Platform

    JVM에서 테스트 프레임워크를 시작. JUnit과 빌드 도구와 같은 클라이언트 사이의 안정적이고 강력한 인터페이스를 정의

    구조 (2/3) - JUnit Jupiter

    JUnit 5에서 테스트를 작성하기 위한 새로운 프로그래밍 및 확장 모델이 포함되어 있음

    JUnit 4와 비교하여 새로운 주석

    • @TestFactory - 동적 테스트를 위한 테스트 팩토리 인 메서드를 나타냄

    • @DisplayName - 테스트 클래스 또는 테스트 메서드의 사용자 정의 표시 이름을 정의

    • @Nested - 주석이 달린 클래스가 중첩된 비정적 테스트 클래스임을 나타냄

    • @Tag - 필터링 테스트를 위한 태그 선언

    • @ExtendWith - 사용자 정의 확장명을 등록하는데 사용

    • @BeforeEach - 어노테이션이 있는 메서드가 각 테스트 메서드 전에 실행됨을 나타냄(이전의 @Before)

    • @AfterEach - 어노테이션이 있는 메서드가 각 테스트 메서드 후에 실행됨을 나타냄(이전의 @After)

    • @BeforeAll - 어노테이션이 있는 메서드가 현재 클래스의 모든 테스트 메서드 전에 실행됨을 나타냄(이전의 @BeforeClass)

    • @AfterAll - 어노테이션이 있는 메서드가 현재 클래스의 모든 테스트 메서드 후에 실행됨을 나타냄(이전의 @AfterClass)

    • @Disable - 테스트 클래스 또는 메서드를 비활성화하는데 사용(이전의 @Ignore)

    구조 (3/3) - JUnit Vintage

    JUnit 5 플랫폼에서 JUnit 3 & 4 기반 테스트 지원

    기본 주석(1/3) - 테스트 전. @BeforeAll & @BeforeEach

    @BeforeAll 어노테이션이 있는 메서드는 static이여야 함, 그렇지 않을 경우 코드가 컴파일되지 않음

    @BeforeAll
    static void setup() {
        log.info("@BeforeAll - executes once before all test methods in this class");
    }
    
    @BeforeEach
    void init() {
        log.info("@BeforeEach - executes before each test method is this class");
    }

    기본 주석(2/3) - 테스트 중. @DisplayName & @Disable

    새로운 주석을 이용하여 표시 이름을 변경하거나 주석이 있는 메서드를 비활성화할 수 있음

    @DisplayName("Single test successful")
    @Test
    void testSingleSuccessTest() {
        log.info("Success");
    }
    
    @Test
    @Disable("Not implemented yet")
    void testShowSomthing() {
    }

    기본 주석(3/3) - 테스트 후. @AfterEach & @AfterAll  

    @AfterAll 메서드도 static 메서드여야 함

    @AfterEach
    void tearDown() {
        log.info("@AfterEach - executed after each test methods.");
    }
    
    @AfterAll
    static void done() {
        log.info("@AfterAll - executed after all test methods.");
    }

    Assertions & Assumptions

    org.junit.jupiter.api.Assertions로 이동되었고, 람다식을 사용할 수 있도록 개선됨

    assertAll()로 그룹화 가능하지만, 오류의 정확한 위치 파악을 위해 복잡한 Assertions를 만드는 것이 더 안전함

    코드는 아직 이해 못함 [LINK]

    Assumptions는 특정 조건이 충족되는 경우에만 테스트를 실행하는데 사용

    일반적으로 테스트가 제대로 실행되기 위해 필요한 외부 조건에 사용되지만 테스트 대상과 직접 관련이 없음

    실패하면 TestAbortedException 발생되고 테스트는 건너뜀. 람다식 사용 가능

    package study;
    
    import org.junit.jupiter.api.Test;
    
    import static org.junit.Assert.assertEquals;
    import static org.junit.Assume.assumeFalse;
    import static org.junit.Assume.assumeTrue;
    import static org.junit.jupiter.api.Assumptions.assumingThat;
    
    public class TestABC {
        @Test
        void trueAssumption() {
            assumeTrue(5 > 1);
            assertEquals(5 + 2, 7);
        }
    
        @Test
        void falseAssumption() {
            assumeFalse(5 < 1);
            assertEquals(5 + 2, 7);
        }
    
        @Test
        void assumptionThat() {
            String someString = "Just a string";
            assumingThat(
                    someString.equals("Just a string"),
                    () -> assertEquals(2 + 2, 4)
            );
        }
    }

    코드는 아직 이해 못함 [LINK]

    Exception Testing

    JUnit5에는 두 가지 예외 테스트 방법이 있음

    두 가지 모두 assertThrows() 메서드를 사용하여 구현

    첫 번째 예는 발생된 예외의 세부 사항을 확인하는데 사용되며, 두 번째 예는 예외 유형의 유효성을 검사함

    package study;
    
    import org.junit.jupiter.api.Test;
    
    import static org.junit.jupiter.api.Assertions.assertEquals;
    import static org.junit.jupiter.api.Assertions.assertThrows;
    
    public class TestABC {
        @Test
        void shouldThrowException() {
            Throwable exception = assertThrows(UnsupportedOperationException.class, () -> {
                throw new UnsupportedOperationException("Not supported");
            });
            assertEquals(exception.getMessage(), "Not supported");
        }
    
        @Test
        void assertThrowsException() {
            String str = null;
            assertThrows(IllegalArgumentException.class, () -> {
                Integer.valueOf(str);
            });
        }
    }

    Test Suites

    - 아직 이해 못함 [LINK]

    Dynamic Tests

    - 아직 이해 못함 [LINK]

    @Test Annotation

    단위 및 회귀 테스트를 위한 강력한 도구를 제공

    테스트로 인식되도록 추가하는 어노테이션 @Test

    Test는 private이면 안되고, 값을 return해도 안 됨, 안그럼 무시됨

    JUnit 5 Assertions

    package study;
    
    import org.junit.jupiter.api.Test;
    
    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Optional;
    import java.util.function.BooleanSupplier;
    
    import static java.time.Duration.ofSeconds;
    import static java.util.Arrays.asList;
    import static org.junit.jupiter.api.Assertions.*;
    
    public class TestABC {
    
        // assertArrayEquals - 배열이 같은지 비
        @Test
        public void whenAssertingArraysEquality_thenEqual() {
            char[] expected = {'J', 'u', 'p', 'i', 't', 'e', 'r'};
            char[] actual = "Jupiter".toCharArray();
    
            assertArrayEquals(expected, actual, "Arrays should be equal");
        }
    
        // assertEquals - 두 개의 float이 같다고 간단히 주장
        @Test
        public void whenAssertingEquality_thenEqual() {
            float square = 2 * 2;
            float rectangle = 2 * 2;
    
            assertEquals(square, rectangle);
        }
    
        // assertEquals - 두 개의 float이 델타에 의해 예상 값과 다르다고 주
        @Test
        public void whenAssertingEqualityWithDelta_thenEqual() {
            float square = 2 * 2;
            float rectangle = 3 * 2;
            float delta = 2;
    
            assertEquals(square, rectangle, delta);
        }
    
        // assertTrue - True인지
        @Test
        public void whenAssertingConditions_thenVerified() {
            assertTrue(5 > 4, "5 is greater the 4");
            assertTrue(null == null, "null is equal to null");
        }
    
        // assertFalse - False인지
        @Test
        public void givenBooleanSupplier_whenAssertingCondition_thenVerified() {
            BooleanSupplier condition = () -> 5 > 6;
    
            assertFalse(condition, "5 is not greater then 6");
        }
    
        // assertNotNull - 객체가 널이 아님
        @Test
        public void whenAssertingNotNull_thenTrue() {
            Object dog = new Object();
    
            assertNotNull(dog, () -> "The dog should not be null");
        }
    
        // assertNull - 객체가 널임
        @Test
        public void whenAssertingNull_thenTrue() {
            Object cat = null;
    
            assertNull(cat, () -> "The cat should be null");
        }
    
        // assertSame - 같은 객체 참조
        @Test
        public void whenAssertingSameObject_thenSuccessfull() {
            String language = "Java";
            Optional<String> optional = Optional.of(language);
    
            assertSame(language, optional.get());
        }
    
        // assertNotSame - 다른 객체 참조
        @Test
        public void whenAssertingNotSameObject_thenSuccessfull() {
            String language = "Java";
            String optional = new String("Java");
    
            assertNotSame(language, optional);
        }
    
        // fail - 근본적인 원인을 사용해 테스트를 강제 실패
        @Test
        public void whenFailingATest_thenFailed() {
            // Test not completed
            fail("FAIL - test not completed");
        }
    
        // assertAll - 모든 어설션이 실행, 오류가 함께 보고되는 그룹화된 어선셜 그룹 생성 가능 및 이름 추가 가능
        @Test
        public void givenMultipleAssertion_whenAssertingAll_thenOK() {
            assertAll(
                    "heading",
                    () -> assertEquals(4, 2 * 2, "4 is 2 times 2"),
                    () -> assertEquals("java", "JAVA".toLowerCase()),
                    () -> assertEquals((Byte) null, null, "null is equal to null")
            );
        }
    
        // assertIterableEquals - 전체 Iterator하여 값 비교
        @Test
        public void givenTwoLists_whenAssertingIterables_thenEquals() {
            Iterable<String> al = new ArrayList<>(asList("Java", "Junit", "Test"));
            Iterable<String> ll = new LinkedList<>(asList("Java", "Junit", "Test"));
            // Iterator로 비교함
            assertIterableEquals(al, ll);
        }
    
        // assertLinesMatch - 예상 목록 문자열과 실제 문자열이 같은지 비교
        @Test
        public void whenAssertingEqualityListOfStrings_thenEqual() {
            List<String> expected = asList("Java", "\\d+", "JUnit");
            List<String> actual = asList("Java", "11", "JUnit");
            /* 예상 라인이 실제 라인과 같은지 확인하십시오. 그렇다면 다음 쌍으로 계속됩니다
             * 예상되는 줄을 정규식으로 취급하고 String 으로 검사를 수행합니다 . matches () 메소드. 그렇다면 다음 쌍으로 계속됩니다
             * 예상 라인이 빨리 감기 마커인지 확인하십시오. 예인 경우 빨리 감기를 적용하고 1 단계부터 알고리즘을 반복하십시오.
             */
            assertLinesMatch(expected, actual);
        }
    
        // assertNotEquals - 예상 값과 실제 값이 다름
        @Test
        public void whenAssertingEquality_thenNotEqual() {
            Integer value = 5; // result of an algorithm
            // 둘다 널인 경우엔 실패
            assertNotEquals(0, value, "The result cannot be 0");
        }
    
        // assertThrows -  실행 파일이 지정된 예외 유형을 throw, 예외가 발생하지 않거나 다른 유형의 예외가 발생하면 실패
        @Test
        void whenAssertingException_thenThrown() {
            Throwable exception = assertThrows(
                    IllegalArgumentException.class,
                    () -> {
                        throw new IllegalArgumentException("Exception message");
                    }
            );
            assertEquals("Exception message", exception.getMessage());
        }
    
        /* assertTimeout 실행이 Timeout 전에 끝나도록, 단 실행 파일이 호출 코드와 동일한 스레드에서 실행되어 시간 초과시 실행 파일 중단되지 않
         * assertTimeoutPreemptively를 사용하면 시간초과시 실행파일 중단
         */
        @Test
        public void whenAssertingTimeout_thenNotExceeded() {
            assertTimeout(
                    ofSeconds(2),
                    () -> {
                        // code that requires less then 2 minutes to execute
                        Thread.sleep(1000);
                    }
            );
        }
    }

    JUnit Parameterized Test

    개요

    parameterized tests 기능 사용시 매개 변수가 다른 단일 테스트 방법을 여러 번 실행할 수 있음

    @ParameterizedTest 사용

    의존성

    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-params</artifactId>
        <version>5.4.2</version>
        <scope>test</scope>
    </dependency>

    Gradle 지정

    testCompile("org.junit.jupiter:junit-jupiter-params:5.4.2")

    @ValueSource 특징

    package study;
    
    import org.junit.jupiter.params.ParameterizedTest;
    import org.junit.jupiter.params.provider.ValueSource;
    
    import static org.junit.Assert.assertTrue;
    
    public class TestABC {
    
        public static boolean isOdd(int number) {
            return number % 2 != 0;
        }
    
        @ParameterizedTest
        @ValueSource(ints = {1, 3, 5, -3, 15, Integer.MAX_VALUE}) // six numbers
        void isOdd_ShouldReturnTrueForOddNumbers(int number) {
            assertTrue(isOdd(number));
        }
    
        public static boolean isBlank(String input) {
            return input == null || input.trim().isEmpty();
        }
    
        @ParameterizedTest
        @ValueSource(strings = {"", "  "})
        void isBlank_ShouldReturnTrueForNullOrBlankStrings(String input) {
            assertTrue(isBlank(input));
        }
    }

     

    아래 부분만 지원

    • short  shorts 속성 사용)

    • 바이트  bytes 속성 포함)

    • int ( int 속성 사용)

    • long  ( longs 속성 사용)

    • float ( floats 속성 사용)

    • double ( doubles 속성 사용)

    • char ( chars 속성 포함)

    • java.lang.String ( 문자열 속성 포함)

    • java.lang.Class ( classs 속성 포함)

    한 번 테스트시 하나의 값만 가능 (즉, 두 값 입력시 각각 한 번씩 두 번 테스트 하는 것)

    Null은 지원하지 않음(JUnit 5.4부터 다른 어노테이션으로 지원)

    @NullSource (JUnit 5.4 ~ ) & EmptySource

    package study;
    
    import org.junit.jupiter.params.ParameterizedTest;
    import org.junit.jupiter.params.provider.EmptySource;
    import org.junit.jupiter.params.provider.NullAndEmptySource;
    import org.junit.jupiter.params.provider.NullSource;
    import org.junit.jupiter.params.provider.ValueSource;
    
    import static org.junit.Assert.assertTrue;
    
    public class TestABC {
        public static boolean isBlank(String input) {
            return input == null || input.trim().isEmpty();
        }
    
        @ParameterizedTest
        @NullSource
        void isBlank_ShouldReturnTrueForNullInputs(String input) {
            assertTrue(isBlank(input));
        }
    
        @ParameterizedTest
        @EmptySource
        void isBlank_ShouldReturnTrueForEmptyStrings(String input) {
            assertTrue(isBlank(input));
        }
    
        @ParameterizedTest
        @NullAndEmptySource
        void isBlank_ShouldReturnTrueForNullAndEmptyStrings(String input) {
            assertTrue(isBlank(input));
        }
    
        @ParameterizedTest
        @NullAndEmptySource
        @ValueSource(strings = {"  ", "\t", "\n", ""})
        void isBlank_ShouldReturnTrueForAllTypesOfBlankStrings(String input) {
            assertTrue(isBlank(input));
        }
    }

    @NullSource - 단일 널 값을 매개변수화된 테스트 메서드에 전달 가능

    @EmptySource - 빈 값을 전달, 하나의 빈 인수를 전달함

    @NullAndEmptySource - NullSource + EmptySource

    @통합하여 (중복) 사용도 가능함

    열거형(Enum)

    @EnumSource 주석을 사용하면 열거형 값으로 테스트를 할 수 있음

    @ValueSource처럼 테스트 실행당 하나의 인수를 전달할 때 사용(매우 유사)

    package study;
    
    import org.junit.jupiter.params.ParameterizedTest;
    import org.junit.jupiter.params.provider.EnumSource;
    
    import java.time.Month;
    import java.util.EnumSet;
    
    import static org.junit.Assert.assertEquals;
    import static org.junit.Assert.assertTrue;
    
    public class TestABC {
        // EnumSource(열거타입)
        @ParameterizedTest
        @EnumSource(Month.class) // passing all 12 months
        void getValueForAMonth_IsAlwaysBetweenOneAndTwelve(Month month) {
            int monthNumber = month.getValue();
            assertTrue(monthNumber >= 1 && monthNumber <= 12);
        }
    
        // names 속성을 이용하여 일부 제외 가능
        @ParameterizedTest
        @EnumSource(value = Month.class, names = {"APRIL", "JUNE", "SEPTEMBER", "NOVEMBER"})
        void someMonths_Are30DaysLong(Month month) {
            final boolean isALeapYear = false;
            assertEquals(30, month.length(isALeapYear));
        }
    
        // mode 속성을 EXCLUDE로 두면, 일부 선택 가능(names)
        @ParameterizedTest
        @EnumSource(
                value = Month.class,
                names = {"APRIL", "JUNE", "SEPTEMBER", "NOVEMBER", "FEBRUARY"},
                mode = EnumSource.Mode.EXCLUDE)
        void exceptFourMonths_OthersAre31DaysLong(Month month) {
            final boolean isALeapYear = false;
            assertEquals(31, month.length(isALeapYear));
        }
    
        // names 속성에 정규표현식도 가능, mode 체크
        @ParameterizedTest
        @EnumSource(value = Month.class, names = ".+BER", mode = EnumSource.Mode.MATCH_ANY)
        void fourMonths_AreEndingWithBer(Month month) {
            EnumSet<Month> months =
                    EnumSet.of(Month.SEPTEMBER, Month.OCTOBER, Month.NOVEMBER, Month.DECEMBER);
            assertTrue(months.contains(month));
        }
    }

    CSV Literals

    @CsvSource는 쉼표로 구분된 값의 배열을 수용하며, 각 배열 항목은 CSV 파일의 라인에 해당

    CSV형태로 ""로 묶어주고, 여러 개의 인수를 보낼 수 있는 형태. 여러 개의 인수를 여러 번 보내줄 수 있음

    package study;
    
    import org.junit.jupiter.params.ParameterizedTest;
    import org.junit.jupiter.params.provider.CsvSource;
    
    import static org.junit.Assert.assertEquals;
    
    public class TestABC {
        @ParameterizedTest
        @CsvSource({"test,TEST", "tEst,TEST", "Java,JAVA"})
        void toUpperCase_ShouldGenerateTheExpectedUppercaseValue(String input, String expected) {
            String actualValue = input.toUpperCase();
            assertEquals(expected, actualValue);
        }
    
        // delimiter 속성으로 구분자 지정 가능 (default = ,)
        @ParameterizedTest
        @CsvSource(value = {"test:test", "tEst:test", "Java:java"}, delimiter = ':')
        void toLowerCase_ShouldGenerateTheExpectedLowercaseValue(String input, String expected) {
            String actualValue = input.toLowerCase();
            assertEquals(expected, actualValue);
        }
    }

    CSV File

    @CsvFileSource 이용하여 CSV 파일을 읽을 수 있음

    numLinesToSkip의 경우 "n"개의 행을 건너띌 때 유용 (default = 0)

    예제와 같은 파일의 경우 1행씩 건너띄었으므로 1

    delimiter 지정 가능(@CsvSource와 동일)

    lineSeparator이용하여 줄구분 기호 지정 가능(줄바꿈이 기본값)

    encoding이용하여 인코딩 설정 가능(UTF-8)기본 값

    // CSV 파일
    input,expected
    test,TEST
    tEst,TEST
    Java,JAVA
    
    // CsvFileSource 이용
    @ParameterizedTest
    @CsvFileSource(resources = "/data.csv", numLinesToSkip = 1)
    void toUpperCase_ShouldGenerateTheExpectedUppercaseValueCSVFile(
      String input, String expected) {
        String actualValue = input.toUpperCase();
        assertEquals(expected, actualValue);
    }

    Method

    보다 복잡한 인수를 제공하는 방법

    @MethodSource("사용할 스트림을 반환하는 정적 메서드명")  > Stream을 반환하지 않고 List와 유사한 컬렉션 인터페이스를 반환해도 됨

    package study;
    
    import org.junit.jupiter.params.ParameterizedTest;
    import org.junit.jupiter.params.provider.Arguments;
    import org.junit.jupiter.params.provider.MethodSource;
    
    import java.util.stream.Stream;
    
    import static org.junit.Assert.assertEquals;
    import static org.junit.Assert.assertTrue;
    
    public class TestABC {
        public static boolean isBlank(String input) {
            return input == null || input.trim().isEmpty();
        }
    
        @ParameterizedTest
        @MethodSource("provideStringsForIsBlank")
        void isBlank_ShouldReturnTrueForNullOrBlankStrings(String input, boolean expected) {
            assertEquals(expected, isBlank(input));
        }
    
        private static Stream<Arguments> provideStringsForIsBlank() {
            return Stream.of(
                    Arguments.of(null, true),
                    Arguments.of("", true),
                    Arguments.of("  ", true),
                    Arguments.of("not blank", false)
            );
        }
    
        // 테스트 호출마다 하나의 인수만 제공할 경우 인수 추상화 사용하지 않아도 됨
        @ParameterizedTest
        @MethodSource // 이름 없으면 테스트 메서드와 동일한 이름의 메서드를 실행
        void isBlank_ShouldReturnTrueForNullOrBlankStringsOneArgument(String input) {
            assertTrue(isBlank(input));
        }
    
        private static Stream<String> isBlank_ShouldReturnTrueForNullOrBlankStringsOneArgument() {
            return Stream.of(null, "", "  ");
        }
    }

    FQN#methodName 형식을 사용하면 외부 정적 방법을 참조할 수 있다.

    class StringsUnitTest {
        @ParameterizedTest
        @MethodSource("com.baeldung.parameterized.StringParams#blankStrings")
        void isBlank_ShouldReturnTrueForNullOrBlankStringsExternalSource(String input) {
            assertTrue(Strings.isBlank(input));
        }
    }
     
    public class StringParams {
        static Stream<String> blankStrings() {
            return Stream.of(null, "", "  ");
        }
    }

    Customs

    Custom Argument ProviderCustom Annotation도 정의하여 사용 가능

    Argument Conversion(변환)

    아직 안읽어봄 [LINK]

    Argument Accessor(접근자)

    아직 안읽어봄 [LINK]

    Argument Aggregator(수집기)

    아직 안읽어봄 [LINK]

    Customizing Display Names(표시 이름 사용자 정의)

     

    ├─ someMonths_Are30DaysLongCsv(Month)

    │     │  ├─ [1] APRIL

    │     │  ├─ [2] JUNE

    │     │  ├─ [3] SEPTEMBER

    │     │  └─ [4] NOVEMBER

    이런식으로 나오던 것을 아래 코드와 같이 실행하면 사용자가 정의한 대로 나타나는 것을 볼 수 있음

    package study;
    
    import org.junit.jupiter.params.ParameterizedTest;
    import org.junit.jupiter.params.provider.EnumSource;
    
    import java.time.Month;
    
    import static org.junit.Assert.assertEquals;
    
    public class TestABC {
        @ParameterizedTest(name = "{index} {0} is 30 days long")
        @EnumSource(value = Month.class, names = {"APRIL", "JUNE", "SEPTEMBER", "NOVEMBER"})
        void someMonths_Are30DaysLong(Month month) {
            final boolean isALeapYear = false;
            assertEquals(30, month.length(isALeapYear));
        }
    }

    ├─ someMonths_Are30DaysLong(Month)

    │     │  ├─ 1 APRIL is 30 days long

    │     │  ├─ 2 JUNE is 30 days long

    │     │  ├─ 3 SEPTEMBER is 30 days long

    │     │  └─ 4 NOVEMBER is 30 days long

    {index}는 호출 인덱스, {argument}는 쉼표로 구분된 전체 인수 목록에 대한 자리 표시자, {0}, {1},,, 은 개별 주장에 대한 자리 표시자

    Gradle Java Project에서 5.4를 사용하려면?

    build.gradle의 dependencies를 다음과 같이 수정

    dependencies {
        testCompile('org.junit.jupiter:junit-jupiter:5.4.2')
        testCompile('org.assertj:assertj-core:3.11.1')
    }

    Gradle Java Project에서 4.12를 사용하려면?

    dependencies {
        testCompile group: 'junit', name: 'junit', version: '4.12'
        implementation 'org.junit.jupiter:junit-jupiter'
        implementation 'org.junit.jupiter:junit-jupiter'
        implementation 'org.junit.jupiter:junit-jupiter'
        implementation 'org.junit.jupiter:junit-jupiter'
        implementation 'org.junit.jupiter:junit-jupiter'
        implementation 'org.junit.jupiter:junit-jupiter'
    }

    Gradle Java Project에서 5.4 + 4.12를 사용하려면?

    dependencies {
        testCompile('org.junit.jupiter:junit-jupiter:5.4.2')
        testCompile('org.assertj:assertj-core:3.11.1')
        implementation 'junit:junit:4.12'
    }
    반응형

    '우아한 테크코스 > 테크코스' 카테고리의 다른 글

    2주차 리뷰  (0) 2020.02.15
    정규표현식(Regular expression)  (0) 2020.02.08
    1주차 리뷰  (0) 2020.02.08
    [Java] 일급 컬렉션을 알아보자!  (0) 2020.02.06
    [IntelliJ] MAC 단축키 등 알아두기!  (0) 2020.02.06

    댓글

Designed by Tistory.