인프런 워밍업 클럽 BE 2기 - 클린코드 / 테스트코드 발자국 4주차

인프런 워밍업 클럽 BE 2기 - 클린코드 / 테스트코드 발자국 4주차

강의 출처 Practical Testing: 실용적인 테스트 가이드

 

학습 내용

  • 레이어드 아키텍쳐(Layered Architecture)와 테스트 - 노션 정리

  • Test Double

    • Dummy - 아무것도 하지 않는 깡통 객체.

    • Fake - 단순한 형태로 동일한 기능은 수행하나, 프로덕션 초기에는 부족한 객체.

    • Stub - 테스트에서 요청한 것에 대해 미리 준비한 결과를 제공하는 객체. 그 외에는 응답하지 않는다.

    • Spy - stub이면서 호출된 내용을 기록하여 보여줄 수 있는 객체. 일부는 실제 객체처럼 동작하고 일부만 stubbing 할 수 있다.

    • Mock - 행위에 대한 기대를 명세하고, 그에 따라 동작하도록 만들어진 객체.

    • Stub / Mock 의 차이? -> Stub은 상태 검증 / Mock은 행위 검증

  • @Mock, @Spy, @MockBean, @SpyBean, @InjectMocks - 노션 정리

  • BDDMockito - Mockito를 BDD 스타일로 wrap해서 사용.

// given
Mockito.when(mailSendClient.sendEmail(anyString(), anyString(), anyString(), anyString()))
            .thenReturn(true);

// BDDMockito given
BDDMockito.given(mailSendClient.sendEmail(anyString(), anyString(), anyString(), anyString()))
            .willReturn(true);
  • Classicist VS. Mockist

    • 진짜 객체로 테스트를 하고 필요한 경우에만 mocking해서 테스트를 하자. (Classicist)

    • 외부 시스템의 경우 mocking 처리해서 테스트.

  • 하나의 테스트는 하나의 주제만을 가져야 한다. 논리구조(if문, for문..) 같은 경우는 지양하는 것이 좋다. 만약 케이스 확장이 필요하다면 @ParameterizedTest 사용.

     

  • 테스트 환경의 독립성 보장 - given절에서는 값 넣어줄 때 생성자, builder 사용.

  • 테스트 간 독립성 보장 - 두 가지 이상의 테스트가 하나의 자원을 공유할 때 주의해야 한다. 공유 자원(인스턴스)의 여러 시나리오를 테스트 하고 싶을 경우? -> @DynamicTest 사용.

  • Test Fixture

    • 각각의 테스트에서 given이 중복되는 경우 @BeforeEach 에 작성할 경우 주의 해야 할 점 -> 각 테스트 입장에서 알지 못해도 테스트 내용을 이해하는데 문제가 없는지 / 수정해도 모든 테스트에 영향을 주지 않는지 고려해야 한다.

    • data.sql 사용 지양. -> 무엇을 테스트하고 있는지 파악하기 어려울 수 있다.

    • 테스트 클래스마다 builder를 만들어서 각자 필요한 파라미터만 사용한다. (builder class를 만들어서 한 곳에서 관리하는 것이 오히려 복잡도를 늘어나게 한다.)

  • Test Fixture 클렌징

    • deleteAll()

      • mapping된 테이블을 조회 후 delete 한다. 연관된 테이블을 모두 조회한 후 삭제하기 때문에 시간과 비용이 들 수 있다.

      • 테이블의 삭제 순서를 고려해야 될 수 있다.

  • deleteAllInBatch()

    • 테이블의 삭제 순서를 고려해야 한다.

    • 여러 조건들(외래키 조건..)에 따라 삭제가 되지 않을 수 있다.

  • 테스트 환경 통합하기

    • ServiceTest, RepositoryTest

    @ActiveProfiles("test")
    @SpringBootTest
    public abstract class IntegrationTestSupport {
    
        @MockBean
        protected MailSendClient mailSendClient;
    
    }
    • ControllerTest

@WebMvcTest(controllers = {
    OrderController.class,
    ProductController.class
})
public abstract class ControllerTestSupport {

    @Autowired
    protected MockMvc mockMvc;

    @Autowired
    protected ObjectMapper objectMapper;

    @MockBean
    protected OrderService orderService;

    @MockBean
    protected ProductService productService;

}
  • private 메서드의 테스트는 하지 말아야 한다. 꼭 해야 된다면 따로 객체를 분리해서 테스트를 할 수 있다.

  • 테스트에서만 필요한 메서드는 만들어도 되지만, 보수적으로 접근해야 한다.

 

미션

미션 1 - Layered Architecture 구조의 레이어별 특징과 테스트 작성법 -> 노션 정리

미션 2 - @Mock, @Spy, @MockBean, @SpyBean, @InjectMocks 차이점 / @BeforeEach 배치 -> 노션 정리

회고

인프런 워밍업 클럽 BE 2기 4주차라니 시간이 어떻게 흘러간지 모르겠다. 이번 주는 특히나 내가 평소 궁금했던 것들에 대한 강의여서 더 집중해서 들었던 것 같다. 바로 프로젝트에 적용 해볼 만 한 내용이 많아서 만족스러웠다. 워밍업 클럽 진도를 따라가는게 쉽지는 않았지만 지나고 보니 포기하지 않고 어떻게든 하려고 노력 했던 것이 많은 도움이 된 것 같다.


댓글을 작성해보세요.

채널톡 아이콘