• TDD연습하기(2) (자바 플레이그라운드 with TDD, 클린 코드)

    2023. 2. 16.

    by. Sohyun


    이어서 문자열 테스트를 주제로 Juint5 문법을 익혀보았다.

     

    1. @BeforeEach로 테스트 전 설정하기.

     - Set의 크기를 확인하기 위해 값을 임의로 입력해보았다.

    테스트의 멱등성을 위해서 시작전 값을 세팅했다가 테스트 후 초기화하는 방법으로 사용할 수 도 있다.

    @BeforeEach -> 테스트 -> @AfterEach

    private Set<Integer> numbers;
        @BeforeEach
        void setUp() {
            numbers = new HashSet<>();
            numbers.add(1);
            numbers.add(1);
            numbers.add(2);
            numbers.add(3);
        }
    
        @Test
        @DisplayName("Set의 크기를 확인")
        void test1() {
            assertThat(numbers.size()).isEqualTo(3);
        }

     

     

    2. ParameterizedTest를 활용해 중복 코드를 제거하기

    • short, byte, int, long, float, double, char, boolean, java.lang.String, java.lang.Class 가능
    • @NullSource,  @EmptySource, @NullAndEmptySource 도 값과 함께 사용 가능
    • @EnumSource, @MethodSource 도 지원함
    • ParameterizedTest도 Test객체로서 동작하므로 Test어노테이션을 삭제해야 한다. ⭐ 
      더보기
      org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter [int arg0] in method 발생
      ⇒ ParameterizedTest와 Test어노테이션을 동시에 사용하는 경우 발생함. 
        @DisplayName("contains() 메소드를 활용해 1, 2, 3의 값이 존재하는지를 확인")
        @ParameterizedTest
        @ValueSource(ints = {1, 2, 3}) // 원하는 타입을 적어준 뒤 리터럴 값을 넣어주면 됩니다.
        void test2(int num) {
            /* 기존의 반복코드
            assertThat(numbers.contains(1)).isTrue();
            assertThat(numbers.contains(2)).isTrue();
            assertThat(numbers.contains(3)).isTrue();
            */
            
            assertThat(numbers.contains(num)).isTrue();
        }

    📖 parameterized tests 더 알아보기 : https://www.baeldung.com/parameterized-tests-junit-5

     


    @CsvSource를 활용하면

    이처럼 예상되는 값을 입력하여 여러개의 테스트가 가능하다.

    @CsvFileSource를 사용하면 CSV파일을 읽어서도 입력이 가능해서 동적으로 테스트가 가능해서 매우 신기했다.

    @DisplayName("입력 값에 따라 결과 값이 다른 경우의 테스트")
        @ParameterizedTest
        @CsvSource(value = {"1:true", "2:true", "3:true", "4:false"}, delimiter = ':')
        void test3(int input, boolean expected) {
            assertThat(numbers.contains(input)).isEqualTo(expected);
    }

     

    split은 구분자를 여러개 사용하는 것이 가능하다.

    value의 구분자에는 escape문자를 사용해도 에러가 나서(내가 잘못 입력한 건지..?) @CsvSource의 delimiter를 바꿔서 사용해 보았다.

    @DisplayName("구분자를 기준으로 분리한 각 숫자의 합을 반환")
    @ParameterizedTest
    @CsvSource(value = {"|0", "1,2|3", "1,2:3|6"}, delimiter = '|')
    void test4(String str, int expected) {
        /* 기존코드
        String str = "";
        String str2 = "1,2";
        String str3 = "1,2:3";*/
    
        int sum = 0;
        if (str != null && str != "") {
            String[] strings = str.split(",|:");
            for(String s : strings) {
                sum+=Integer.parseInt(s);
            }
        }
        assertThat(sum).isEqualTo(expected);
    }

     

    📖 assertj 더 알아보기 : https://www.baeldung.com/introduction-to-assertj

     

    댓글