블로그

[워밍업 클럽 2기 - Clean Code & Test Code] 4주차 발자국

워밍업 클럽 2기: Clean Code & Test Code의 4주차 발자국 작성입니다.3주차 발자국 보러가기 📝 학습 내용Presentation Layer 테스트 작성Mock더 나은 테스트를 작성하기 위한 여러 팁REST Docs ✍ 학습 내용 복습Q. Presentation Layer의 특징은?클라이언트로 부터 입력을 받아서 비즈니스 계층으로 해당 요청을 보내는 계층요청을 제일 먼저 받는 계층입력 데이터에 대한 기본적인 검증을 수행한다Presentation 계층에서의 검증과 Business 계층에서의 검증을 분리해서 생각해야 한다Presentation 계층에서는 보통 형식적인 검증을 한다예시: 필수 입력 값 검사, 데이터 타입 검사, null 검사, 빈 문자열 검사Business 계층에서는 비즈니스 로직에 따른 도메인 유효성 검사가 이루어진다Business 계층으로 부터 결과를 받아서 클라이언트로 반환한다컨트롤러에서 사용하는 요청 DTO가 서비스 계층으로 침투하지 못하도록 컨트롤러 계층에서 서비스 전용 DTO로 변환하는 것을 권장한다(상황에 따라 다를 수 있을것 같다. 만약 받는 포맷이 변할 가능성이 거의 없다면, 그냥 컨트롤러의 DTO를 쭉 사용해도 괜찮지 않을까 생각이 된다.)Q. Presentation Layer의 테스트 방법은?Business, Persistence 계층을 모킹해서 테스트한다MockMvc 같은 도구를 사용해서 HTTP요청과 응답을 시뮬레이션 한다모킹을 위해서 Mockito 같은 프레임워크를 사용할 수 있다 Q. Test Double의 종류를 정리해보자면?Dummy: 아루런 동작도 하지 않는 객체. 잘 사용되진 않지만, 보통 파라미터 전달용으로 사용된다.Fake: 실체 객체와 동일한 기능은 수행하지만, 프로덕션 용도로 사용하기에는 적합하지 않은 객체.예시: 인메모리로 맵을 사용해서 가짜 레포지토리를 구현하는 경우Stubs: 테스트에서의 요청에 대해 미리 준비된 결과를 제공하는 객체. 미리 반환할 데이터가 정의되어 있고, 호출하는 경우 해당 데이터를 반환한다. 미리 정의되어 있지 않은 것들은 응답하지 않는다.Spies: Stub이지만 정복 기록도 함께하는 객체. 호출 여부, 호출 횟수 등의 정보를 기록할 수 있다. 일부는 실제 객체 처럼 동작하고, 일부는 Stubbing할 수 있다.Mocks: 행위에 대한 기대를 명세하고, 그 명세에 따라 동작되도록 설계 된 객체. 그러니깐 개발자가 직접 그 객체의 행동을 관리하는 객체이다.Q. Stub과 Mock을 구분하는 기준은?Stub : 상태 검증(State Verification)Mock : 행동 검증(Behavior Verification) TIP. 테스트 작성을 위한 여러 팁을 정리해보면Mockito 프레임워크를 한번 래핑하는 BDD Mockito 프레임워크를 사용해서 조금 더 자연스러운 API 네이밍으로 프레임워크를 사용할 수 있다테스트 간의 독립성을 보장하자 테스트에서 전역 변수를 정의해서 사용하는 것은 권장하지 않는다@BeforeEach또는 @AfterEach 메서드를 사용한 레포지토리 클렌징@Transactional사용 Test Fixture용 클래스를 따로 분리해서 사용하는 것은 권장하지 않는다Test Fixture를 @BeforeEach를 사용한 셋업 메서드에서 사용하는 경우, 중복 제거보다 해당 테스트에 해당 내용을 알아야하는지 고려해보고 적용하자테스트 내용은 동일한데 입력값만 변경해보면서 테스트 해보고 싶으면 @ParameterizedTest 사용private메서드에 대한 테스트가 필요하다면 해당 메서드의 책임을 분리할지 고민해본다단순히 테스트하기 위해서 public으로 열어두는 것은 권장하지 않는다 Q. REST Docs vs Swagger의 차이는?REST Docs테스트를 통과해야 문서가 만들어지기 때문에 신뢰도가 높다프로덕션 코드에 비침투적이다코드의 양이 많고 설정이 상대적으로 어렵다Swagger적용이 쉽다문서에서 바로 API 호출이 가능하다애노테이션을 달아줘야 하기 때문에 프로덕션 코드에 침투적이다🤔 회고워밍업 클럽의 마지막 주차가 되었다. 강의 양이 많아도 내가 정말 필요한 내용을 담아서 만들어져있어서, 시간 가는 줄 모르고 시청했다.강의와 미션을 따라가면서 학습에 많은 도움을 받았다. 만약 워밍업 클럽 3기가 있다면 다시 참가할 예정이다.지금까지 학습 내용을 다시 복습해보고 더 나아가서 프로젝트에 적용하는 것이 목표이다. 🔍 참고Practical Testing: 실용적인 테스트 가이드

백엔드테스트코드워밍업클럽2기백엔드발자국4주차회고

miiro

[인프런 워밍업 스터디 클럽 1기] BE 4주차 회고록

네 번째 발자국자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]를 수강하고인프런 워밍업 클럽에 참여하여 쓰는 네 번째 회고록입니다.학습 내용build.gradle빌드 스크립트라고 불린다.gradle을 이용하여 프로젝트를 빌드하고 의존성을 관리하기 위해 작성되었다.현재는 groovy 언어를 사용해 작성되어있고, kotlin 언어를 사용할 수도 있다. 플러그인plugins { id 'java' id 'org.springframework.boot' version '3.1.11' id 'io.spring.dependency-management' version '1.1.4' } org.springframework.boot 플러그인스프링을 빌드했을 때 실행 가능한 jar 파일이 나오게 도와준다.스프링 애플리케이션의 실행을 도와준다.이 외의 플러그인들이 적용될 수 있도록 해준다.io.spring.dependency-management 플러그인외부 라이브러리, 프레임워크의 버전 관리의존성 처리하는 데 사용java 플러그인java 프로젝트 개발 시 필요한 기능 추가JVM 언어 Gradle 플러그인의 사용할 수 있는 기반 마련 그룹group = 'sample' version = '0.0.1-SNAPSHOT' java { sourceCompatibility = '17' }group프로젝트 그룹빌드 결과물에 프로젝트 그룹에 대한 정보가 들어있다.version프로젝트 버전sourceCompatibility프로젝트가 사용하고 있는 JDK 버전 레포지토리repositories { mavenCentral() }외부 라이브러리/ 프레임워크를 가져오는 장소 설정 의존성(dependencies)dependencies { // Spring boot implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-validation' // test testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' // lombok compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' //mysql runtimeOnly 'com.mysql:mysql-connector-j' }사용하는 라이브러리/프레임워크 표시implementation : 해당 의존성을 항시 사용한다.runtimeOnly : 코드를 실행할때에만 의존성을 사용한다.testImplementation : 테스트코드를 컴파일하거나 실행할 때 항시 사용한다.Spring과 SpringBoot의 차이점간편한 설정스프링은 강력한 기능을 제공한다.ex) IoC/DI, AOP, PSA ..기능을 사용하기 위해 xml 설정을 해야했는데 양이 많았다. -> 어노테이션 기반의 설정으로 변경하고 기본적으로 필요한 것들은 모두 자동 설정간단한 의존성 관리Spring을 사용할 때는 개발에 필요한 라이브러리/프레임워크를 모두 기입해야했다.의존성 관리가 힘들기에 starter로 묶어서 관리강력한 확장성Springboot 내부에 tomcat이 있기에 따로 설정할 필요가 없다.MSA에 적합한 모니터링application.yml 파일YAML 문법Yet Another Markup Language(또 다른 마크업 언어)YMAL Ain't Markup Language(마크업 언어가 아니다)확장자 : .yaml 또는 .ymlkey : value 형식으로 데이터를 정의한다.각 계층은 들여쓰기를 통해 구분하게 되며, 이를 통해 중복을 제거할 수 있다.value에는 참/거짓, 숫자, 문자열이 들어갈 수 있다.value에는 배열도 들어갈 수 있다. - 를 활용한다.#을 이용하면 주석을 사용할 수 있다.application.propertiesdev profile 사용application-dev.properties 파일 생성Lombokgetter/setter, 생성자와 같은 반복되는 보일러 플레이트 코드(boiler plate code)를 제거할 수 있다.dependencies 추가compileOnly 'org.projectlombok:lombok'annotationProcessor 추가annotationProcessor 'org.projectlombok:lombok'Spring Boot 2.7.x -> 3.0.x 변경점java 최소 버전이 17로 업그레이드스프링 프로젝트, third-party library 버전 업그레이드AOT 기초 작업AOT(Ahead Of Time) : 빌드 시 스프링 애플리케이션을 분석하고 최적화하는 도구애플리케이션 시작 시간과 메모리 사용량을 줄일 수 있게 해준다.javax -> jakarta 패키지로 변경모니터링 기능 강화 과제 내용이번 프로젝트에서는 출퇴근 사내 시스템으로써, 회사 내 팀과 직원 관리, 출퇴근 관리, 그리고 연차 관리 기능을 설계하였습니다. 기본적인 기술 스택으로는 Java 17 / Springboot 3.x.x으로 구성하여 팀 관리에서는 팀 이름을 필수로 등록하고 팀 정보를 조회할 수 있는 기능을 구현했습니다. 직원 관리에서는 직원의 이름, 매니저 여부, 입사 날짜, 생일을 등록하고, 직원 정보를 조회할 수 있게 했습니다. 출퇴근 관리에서는 직원의 출근 및 퇴근 기능을 구현하였으며, 직원의 근무 시간을 날짜별로 조회할 수 있도록 하였습니다. 연차 관리에서는 직원이 연차를 신청하고, 남아있는 연차를 조회할 수 있는 기능을 제공했습니다. 특히, 연차 신청 시 팀마다 다른 등록 기간을 적용하여 유연성을 높였습니다. 📋 미니 프로젝트 Github : commuting-system회고이번 프로젝트를 통해 팀, 직원, 출퇴근, 연차 관리를 통합적으로 설계하는 경험을 쌓았습니다. 팀 관리에서는 팀의 필수 정보를 명확히 정의하고, 팀 조회 기능을 통해 팀 운영의 투명성을 높였습니다. 직원 관리에서는 직원의 기본 정보를 체계적으로 관리할 수 있게 되었고, 매니저 여부와 같은 역할 분류를 통해 조직의 구조를 명확히 파악할 수 있었습니다. 출퇴근 관리에서는 출퇴근 예외 처리와 날짜별 근무 시간 조회 기능을 통해 직원들의 근태를 정확히 관리할 수 있었습니다. 연차 관리에서는 연차 신청과 조회 기능을 통해 직원들이 연차를 효율적으로 사용할 수 있도록 했습니다. 팀마다 다른 연차 등록 기간을 적용함으로써 조직의 유연성을 높였습니다. 이 프로젝트를 통해 데이터의 일관성을 유지하면서도 다양한 요구 사항을 충족시키는 설계의 중요성을 깨달았습니다. 또한, 시스템 통합의 복잡성을 이해하고, 사용자 편의성을 고려한 기능 설계의 필요성을 다시 한 번 느꼈습니다.

백엔드인프런워밍업스터디클럽4주차회고록

채널톡 아이콘