2021년 9월 10일

회고

Facts(사실, 객관)

  • 코드숨 5주차 과제 피드백 반영
  • "/products" GET 메서드 요청관련 테스트 수정

Feelings(느낌, 주관)

  • 유닛테스트의 목적
  • 테스트 설명의 목적

Findings(배운 점)

  • 나는 목적에 맞는 유닛테스트와 테스트 설명을 작성하는 사람이다.

Affirmation(자기 선언)

04:44 ~ 05:38

Facts(사실, 객관)

  • 코드숨 5주차 과제 피드백 반영
    • ProductService javadoc 수정(참고
    • NotFoundException 에러 메시지 변경(참고)
    • UserRepository save 메서드 테스트 수정(참고)
    • ProductService getProducts 메서드 테스트 수정(참고)

Feelings(느낌, 주관)

  • 유닛테스트의 목적에 대해 느낀점이 있다.
    • 유닛테스트에서 검증해야하는 부분은 개발자의 의도대로 코드가 작동하는지 여부라고 생각한다.
    • 위의 관점에서 첫번째 테스트보다 두번째 테스트가 더 좋은 테스트라고 할 수 있다.
      • ProductService getProducts 메서드는 ProductRepository findAll 메서드의 리턴값을 그대로 리턴한다.
      • ProductService getProducts 유닛테스트의 핵심은 ProductRepository findAll 메서드의 리턴값을 그대로 리턴하는지 여부이다.
      • ProductRepository findAll 메서드의 리턴값이 어떠한지는 의미가 없다.
@Nested
@DisplayName("ProductService 클래스")
@ExtendWith(MockitoExtension.class)
class ProductServiceTest {
    @InjectMocks
    private ProductService productService;

    @Mock
    private ProductRepository productRepository;

    @Nested
    @DisplayName("getProducts 메서드는")
    class Describe_getProducts {
        ListAssert<Product> subject() {
            return assertThat(productService.getProducts());
        }
        OngoingStubbing<List<Product>> mockSubject() {
            return when(productRepository.findAll());
        }
        @AfterEach
        void afterEach() {
            verify(productRepository).findAll();
        }
        @Nested
        @DisplayName("저장된 Product가 있다면")
        class Context_product_exist {
            @BeforeEach
            void beforeEach() {
                mockSubject()
                    .thenReturn(PRODUCT_LIST);
            }
            @Test
            @DisplayName("Product 목록을 리턴한다.")
            void it_returns_a_product_list() {
                subject()
                    .isNotEmpty();
            }
        }
        @Nested
        @DisplayName("저장된 Product가 없다면")
        class Context_product_empty {
            @BeforeEach
            void beforeEach() {
                mockSubject()
                    .thenReturn(EMPTY_LIST);
            }
            @Test
            @DisplayName("빈 목록을 리턴한다.")
            void it_returns_a_empty_list() {
                subject()
                    .isEmpty();
            }
        }
    }
}
@Nested
@DisplayName("ProductService 클래스")
@ExtendWith(MockitoExtension.class)
class ProductServiceTest {
    @InjectMocks
    private ProductService productService;

    @Mock
    private ProductRepository productRepository;

    @Nested
    @DisplayName("getProducts 메서드는")
    class Describe_getProducts {
        ListAssert<Product> subject() {
            return assertThat(productService.getProducts());
        }

        OngoingStubbing<List<Product>> mockSubject() {
            return when(productRepository.findAll());
        }

        @AfterEach
        void afterEach() {
            verify(productRepository).findAll();
        }

        @Nested
        @DisplayName("ProductRepository findAll 메서드의 리턴값을")
        class Context_product_exist {
            @BeforeEach
            void beforeEach() {
                mockSubject()
                    .thenReturn(PRODUCT_LIST);
            }

            @Test
            @DisplayName("그대로 리턴한다.")
            void it_returns_a_product_list() {
                subject()
                    .matches(
                        outputList -> Arrays.deepEquals(
                            PRODUCT_LIST.toArray(), outputList.toArray()
                        )
                    );
            }
        }
    }
}
  • 테스트의 @DisplayName과 @BeforeEach 또는 @BeforeAll과의 관계에 대해 느낀점이 있다.
    • 첫번째 테스트코드의 테스트 설명@DisplayName("저장된 Product가 있다면")과 @BeforeEach 코드 mockSubject().thenReturn(PRODUCT_LIST);는 의미상의 불일치가 발생하고 있다.
    • 그동안 테스트를 형식적으로 작성했던것 같다.

Findings(배운 점)

  • 유닛테스트의 목적
  • 테스트 설명의 목적

Affirmation(자기 선언)

  • 나는 목적에 맞는 유닛테스트와 테스트 설명을 작성하는 사람이다.

09:05 ~ 10:50

Facts(사실, 객관)

  • "/products" GET 메서드 요청관련 테스트 수정
    • ProductService getProducts 메서드 테스트 수정(참고)
    • ProductRepository findAll 메서드 테스트 수정(참고)
    • ProductController list 메서드 테스트 수성(참고)
    • WebMvcTest 테스트 작성(참고)

Feelings(느낌, 주관)

  • 어떤 절차로 테스트를 작성하는지 감이 좀 오는것 같다.
    • @DataJpaTest -> 유닛테스트 -> @WebMvcTest -> E2E 순서로 작성하면 될것 같다.

Findings(배운 점)

  • 테스트 작성 절차

Affirmation(자기 선언)

  • 나는 체계적으로 테스트를 작성하는 사람이다.

좋은 웹페이지 즐겨찾기