inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

인프런 워밍업 클럽 스터디 3기 - 백엔드 클린 코드, 테스트 코드 4주차 발자국

suover
0

image

image

Readable Code: 읽기 좋은 코드를 작성하는 사고법

Practical Testing: 실용적인 테스트 가이드

강의와 함께한 인프런 워밍업 클럽 스터디 3기 - 백엔드 클린 코드, 테스트 코드 (Java, Spring Boot)

4주차 발자국 입니다.


학습 내용 요약

이번 주에는 Practical Testing: 실용적인 테스트 가이드 강의에서 계층형 아키텍처(Layered Architecture) 의 개념을 다시 한번 정리하고, 스프링 기반 테스트에서 자주 사용하는 Mock/Spy 기법과 관련 애너테이션들을 배웠습니다.

학습 회고


미션

🎯 Day16 미션: Layered Architecture 구조의 레이어별 특징과 테스트 방법

요구사항
Layered Architecture에서 각 레이어가 하는 역할, 특징, 그리고 테스트 방식을 자기만의 언어로 정리하기

나만의 정리

  1. Presentation Layer

    • 역할: 사용자나 외부 시스템의 요청을 받고 응답을 전달. 파라미터 검증, DTO 변환, HTTP 상태 코드 결정 등을 담당.

    • 특징: 비즈니스 로직을 직접 수행하지 않고, 유효성 체크 후 Service 호출 → 결과 반환에 집중.

    • 테스트 방법: 컨트롤러 통합 테스트(@SpringBootTest, @WebMvcTest + MockMvc)를 통해 실제 요청/응답 형식을 모의하거나, 프론트엔드와의 e2e 테스트를 진행해볼 수도 있음.

  2. Business Logic Layer

    • 역할: 애플리케이션의 핵심 규칙, 알고리즘, 트랜잭션 등의 로직 담당.

    • 특징: 여러 Repository를 조합하여 도메인 로직을 수행하고, 예외 처리, Validation 등의 업무 로직을 포괄적으로 관리.

    • 테스트 방법: 단위 테스트를 통해 특정 비즈니스 로직의 정확성을 검증. 필요 시 Repository를 Mock 처리(예: @Mock, @MockBean)하여 DB 의존성을 제거하고 로직만 집중 테스트.

  3. Persistence Layer

    • 역할: 데이터의 저장/조회/수정/삭제 등 영속성 처리에 집중.

    • 특징: 쿼리 작성, DB 연결, CRUD 로직을 추상화한 Repository/DAO 형태로 제공.

    • 테스트 방법: 실제 DB 혹은 In-Memory DB(H2 등)를 활용한 통합 테스트(@DataJpaTest). 쿼리 정확도, 트랜잭션 처리, 성능 등을 검증하기에 좋음.

🎯 Day18 미션 1: @Mock, @MockBean, @Spy, @SpyBean, @InjectMocks의 차이점 정리

요구사항
각 애너테이션이 어떤 환경(단위 테스트/통합 테스트)에서 사용되고, 어떤 특징이 있는지 정리하기

1) @Mock

2) @MockBean

3) @Spy

4) @SpyBean

5) @InjectMocks

🎯 Day18 미션 2: 테스트 시나리오(@BeforeEach, given, when, then) 구성

요구사항
아래 3개의 테스트 메서드가 있을 때, “어떤 준비 로직을 @BeforeEach로 뽑고, 어떤 부분을 각 테스트의 given절에 둘지”, “when절을 어떻게 구성할지”를 구상해보기

예시 테스트 3종

  1. 사용자가 댓글을 작성할 수 있다.

  2. 사용자가 댓글을 수정할 수 있다.

  3. 자신이 작성한 댓글이 아니면 수정할 수 없다.

나의 구성

@BeforeEach
void init() {
    // 공통 데이터를 미리 생성하지 않습니다.
    /*
     * 각 테스트가 각각의 상황(사용자, 게시물, 댓글)을 자유롭게 구성할 수 있도록,
     * 여기서는 사전에 아무것도 세팅해두지 않습니다.
     * 테스트마다 필요한 데이터 타입이나 조건이 다를 수 있으므로,
     * 각 테스트 메서드 내부에서 직접 객체를 생성하고 준비해 주는 방식을 채택했습니다.
     */
}

@DisplayName("사용자가 댓글을 작성할 수 있다.")
@Test
void writeComment() {
    // given
    // 1-1. 사용자 생성에 필요한 내용 준비
    // 1-2. 사용자 생성
    // 1-3. 게시물 생성에 필요한 내용 준비
    // 1-4. 게시물 생성
    // 1-5. 댓글 생성에 필요한 내용 준비

    // when
    // 1-6. 댓글 생성

    // then
    // 검증
}

@DisplayName("사용자가 댓글을 수정할 수 있다.")
@Test
void updateComment() {
    // given
    // 2-1. 사용자 생성에 필요한 내용 준비
    // 2-2. 사용자 생성
    // 2-3. 게시물 생성에 필요한 내용 준비
    // 2-4. 게시물 생성
    // 2-5. 댓글 생성에 필요한 내용 준비
    // 2-6. 댓글 생성

    // when
    // 2-7. 댓글 수정

    // then
    // 검증
}

@DisplayName("자신이 작성한 댓글이 아니면 수정할 수 없다.")
@Test
void cannotUpdateCommentWhenUserIsNotWriter() {
    // given
    // 3-1. 사용자1 생성에 필요한 내용 준비
    // 3-2. 사용자1 생성
    // 3-3. 사용자2 생성에 필요한 내용 준비
    // 3-4. 사용자2 생성
    // 3-5. 사용자1의 게시물 생성에 필요한 내용 준비
    // 3-6. 사용자1의 게시물 생성
    // 3-7. 사용자1의 댓글 생성에 필요한 내용 준비
    // 3-8. 사용자1의 댓글 생성

    // when
    // 3-9. 사용자2가 사용자1의 댓글 수정 시도

    // then
    // 검증
}

미션 회고


회고

다음 목표

  1. 예외 상황 테스트 강화

    • 단순 성공 케이스뿐 아니라, 비정상 입력이나 예외 케이스를 좀 더 체계적으로 정리하고 테스트에 반영.

       

  2. 도메인 별로 테스트 슬라이싱

    • @DataJpaTest, @WebMvcTest 등 스프링이 제공하는 슬라이스 테스트 방식을 적극 활용해 보기.

  3. 테스트 실행 속도 최적화

    • 통합 테스트와 단위 테스트를 적절히 조합하여, 빠르면서도 신뢰성 있는 테스트 환경을 구축해 보기.

이번 4주차에는 계층형 아키텍처를 다시 한번 복습하면서 Mock/Spy, @MockBean/@SpyBean 등 스프링 테스트 환경에서 자주 쓰이는 기법들을 정리하고 적용해 보았습니다. 학습 내용과 미션을 통해 각 레이어가 가진 의미와 책임이 더욱 또렷해졌고, 가짜 객체를 어떻게 잘 활용해야 하는지 감이 잡힌 것 같습니다.

앞으로도 학습 내용을 기록하고 회고하면서, 점점 더 탄탄한 테스트 코드를 작성해 가도록 하겠습니다.

감사합니다!

백엔드 인프런 워밍업클럽 스터디 백엔드 클린 테스트 코드 발자국 회고 3기

답변 0